diff -Nru openldap-2.5.11+dfsg/build/dir.mk openldap-2.5.12+dfsg/build/dir.mk --- openldap-2.5.11+dfsg/build/dir.mk 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/build/dir.mk 2022-05-04 14:57:30.000000000 +0000 @@ -21,7 +21,7 @@ @echo "Making all in `$(PWD)`" @for i in $(SUBDIRS) $(ALLDIRS); do \ echo " Entering subdirectory $$i"; \ - ( cd $$i && $(MAKE) $(MFLAGS) all ); \ + ( cd $$i && $(MAKE) all ); \ if test $$? != 0 ; then exit 1; fi ; \ echo " "; \ done @@ -30,7 +30,7 @@ @echo "Making install in `$(PWD)`" @for i in $(SUBDIRS) $(INSTALLDIRS); do \ echo " Entering subdirectory $$i"; \ - ( cd $$i && $(MAKE) $(MFLAGS) install ); \ + ( cd $$i && $(MAKE) install ); \ if test $$? != 0 ; then exit 1; fi ; \ echo " "; \ done @@ -39,7 +39,7 @@ @echo "Making clean in `$(PWD)`" @for i in $(SUBDIRS) $(CLEANDIRS); do \ echo " Entering subdirectory $$i"; \ - ( cd $$i && $(MAKE) $(MFLAGS) clean ); \ + ( cd $$i && $(MAKE) clean ); \ if test $$? != 0 ; then exit 1; fi ; \ echo " "; \ done @@ -48,7 +48,7 @@ @echo "Making veryclean in `$(PWD)`" @for i in $(SUBDIRS) $(CLEANDIRS); do \ echo " Entering subdirectory $$i"; \ - ( cd $$i && $(MAKE) $(MFLAGS) veryclean ); \ + ( cd $$i && $(MAKE) veryclean ); \ if test $$? != 0 ; then exit 1; fi ; \ echo " "; \ done @@ -57,7 +57,7 @@ @echo "Making depend in `$(PWD)`" @for i in $(SUBDIRS) $(DEPENDDIRS); do \ echo " Entering subdirectory $$i"; \ - ( cd $$i && $(MAKE) $(MFLAGS) depend ); \ + ( cd $$i && $(MAKE) depend ); \ if test $$? != 0 ; then exit 1; fi ; \ echo " "; \ done diff -Nru openldap-2.5.11+dfsg/build/version.var openldap-2.5.12+dfsg/build/version.var --- openldap-2.5.11+dfsg/build/version.var 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/build/version.var 2022-05-04 14:57:30.000000000 +0000 @@ -15,9 +15,9 @@ ol_package=OpenLDAP ol_major=2 ol_minor=5 -ol_patch=11 -ol_api_inc=20511 +ol_patch=12 +ol_api_inc=20512 ol_api_current=1 -ol_api_revision=6 +ol_api_revision=7 ol_api_age=1 -ol_release_date="2022/01/20" +ol_release_date="2022/05/04" diff -Nru openldap-2.5.11+dfsg/CHANGES openldap-2.5.12+dfsg/CHANGES --- openldap-2.5.11+dfsg/CHANGES 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/CHANGES 2022-05-04 14:57:30.000000000 +0000 @@ -1,5 +1,35 @@ OpenLDAP 2.5 Change Log +OpenLDAP 2.5.12 Release (2022/05/04) + Fixed libldap to drop connection when non-LDAP data is received (ITS#9803) + Fixed libldap to allow newlines at end of included file (ITS#9811) + Fixed slapd slaptest conversion of olcLastBind (ITS#9808) + Fixed slapd usage of thread local counters (ITS#9789) + Fixed slapd to clear runqueue task correctly (ITS#9785) + Fixed slapd idletimeout handling (ITS#9820) + Fixed slapd bconfig locking for cn=config replication (ITS#9584) + Fixed slapd syncrepl handling of new sessions (ITS#9584) + Fixed slapd to clear connections on bind (ITS#9799) + Fixed slapd to correctly advance connections index (ITS#9831) + Fixed slapd syncrepl ODSEE replication of unknown attr (ITS#9801) + Fixed slapd-asyncmeta memory leak in keepalive setting (ITS#9802) + Fixed slapd-ldap memory leak in keepalive setting (ITS#9802) + Fixed slapd-meta SEGV on config rewrite (ITS#9802) + Fixed slapd-meta ordering on config rewrite (ITS#9802) + Fixed slapd-meta memory leak in keepalive setting (ITS#9802) + Fixed slapd-monitor SEGV on shutdown (ITS#9809) + Fixed slapd-sql to properly escape filter value (ITS#9815) + Fixed slapo-dynlist dynamic group regression (ITS#9825) + Fixed slapo-pcache SEGV on shutdown (ITS#9809) + Fixed slapo-ppolicy operation handling to be consistent (ITS#9794) + Fixed slapo-translucent to correctly duplicate substring filters (ITS#9818) + Build Environment + Fix compilation with openssl exclusions (ITS#9791) + Fix warnings from make jobserver (ITS#9788) + Fix compiliation with certain versions of gcc (ITS#9790) + Documentation + Fixed slapd.conf(5)/slapd-config(5) syncrepl sizelimit/timelimit documentation (ITS#9804) + OpenLDAP 2.5.11 Release (2022/01/20) Fix broken build release variable diff -Nru openldap-2.5.11+dfsg/contrib/slapd-modules/vc/vc.c openldap-2.5.12+dfsg/contrib/slapd-modules/vc/vc.c --- openldap-2.5.11+dfsg/contrib/slapd-modules/vc/vc.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/contrib/slapd-modules/vc/vc.c 2022-05-04 14:57:30.000000000 +0000 @@ -289,16 +289,14 @@ goto done; } conn->refcnt++; + operation_counter_init( conn->op, op->o_threadctx ); ldap_pvt_thread_mutex_unlock( &vc_mutex ); } else { - void *thrctx; - conn = (vc_conn_t *)SLAP_CALLOC( 1, sizeof( vc_conn_t ) ); conn->refcnt = 1; - thrctx = ldap_pvt_thread_pool_context(); - connection_fake_init2( &conn->connbuf, &conn->opbuf, thrctx, 0 ); + connection_fake_init2( &conn->connbuf, &conn->opbuf, op->o_threadctx, 0 ); conn->op = &conn->opbuf.ob_op; snprintf( conn->op->o_log_prefix, sizeof( conn->op->o_log_prefix ), "%s VERIFYCREDENTIALS", op->o_log_prefix ); diff -Nru openldap-2.5.11+dfsg/debian/changelog openldap-2.5.12+dfsg/debian/changelog --- openldap-2.5.11+dfsg/debian/changelog 2022-05-12 13:07:41.000000000 +0000 +++ openldap-2.5.12+dfsg/debian/changelog 2022-06-13 17:19:52.000000000 +0000 @@ -1,3 +1,17 @@ +openldap (2.5.12+dfsg-0ubuntu0.22.04.1) jammy; urgency=medium + + * New upstream version (LP: #1977627). + - Fixed slapd syncrepl handling of new sessions (ITS#9584) + - Fixed slapd-sql to properly escape filter value (ITS#9815) + (CVE-2022-29155) + [ Already included in 2.5.11+dfsg-1~exp1ubuntu3.1 ] + - More details about this release can be found at: + https://git.openldap.org/openldap/openldap/-/blob/2bda1fa98fbcedc6cd5995ea905427b8bef89f9d/CHANGES + * d/p/CVE-2022-29155.patch: Dropped patch; included in this new upstream + version. + + -- Sergio Durigan Junior Mon, 13 Jun 2022 13:19:52 -0400 + openldap (2.5.11+dfsg-1~exp1ubuntu3.1) jammy-security; urgency=medium * SECURITY UPDATE: SQL injection in experimental back-sql backend diff -Nru openldap-2.5.11+dfsg/debian/patches/CVE-2022-29155.patch openldap-2.5.12+dfsg/debian/patches/CVE-2022-29155.patch --- openldap-2.5.11+dfsg/debian/patches/CVE-2022-29155.patch 2022-05-12 13:07:35.000000000 +0000 +++ openldap-2.5.12+dfsg/debian/patches/CVE-2022-29155.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,274 +0,0 @@ -From 40f3ae4f5c9a8baf75b237220f62c436a571d66e Mon Sep 17 00:00:00 2001 -From: Howard Chu -Date: Wed, 23 Mar 2022 12:43:31 +0000 -Subject: [PATCH] ITS#9815 slapd-sql: escape filter values - -Escape filter values to slapd-sql (CVE-2022-29155) ---- - servers/slapd/back-sql/search.c | 123 +++++++++++++++++++++++++++----- - 1 file changed, 105 insertions(+), 18 deletions(-) - -diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c -index 2168a1553b..d4177f6292 100644 ---- a/servers/slapd/back-sql/search.c -+++ b/servers/slapd/back-sql/search.c -@@ -63,6 +63,38 @@ static void send_paged_response( - ID *lastid ); - #endif /* ! BACKSQL_ARBITRARY_KEY */ - -+/* Look for chars that need to be escaped, return count of them. -+ * If out is non-NULL, copy escape'd val to it. -+ */ -+static int -+backsql_val_escape( Operation *op, struct berval *in, struct berval *out ) -+{ -+ char *ptr, *end; -+ int q = 0; -+ -+ ptr = in->bv_val; -+ end = ptr + in->bv_len; -+ while (ptr < end) { -+ if ( *ptr == '\'' ) -+ q++; -+ ptr++; -+ } -+ if ( q && out ) { -+ char *dst; -+ out->bv_len = in->bv_len + q; -+ out->bv_val = op->o_tmpalloc( out->bv_len + 1, op->o_tmpmemctx ); -+ ptr = in->bv_val; -+ dst = out->bv_val; -+ while (ptr < end ) { -+ if ( *ptr == '\'' ) -+ *dst++ = '\''; -+ *dst++ = *ptr++; -+ } -+ *dst = '\0'; -+ } -+ return q; -+} -+ - static int - backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) - { -@@ -429,6 +461,8 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, - backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; - int i; - int casefold = 0; -+ int escaped = 0; -+ struct berval escval, *fvalue; - - if ( !f ) { - return 0; -@@ -462,50 +496,68 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, - - BER_BVZERO( &bv ); - if ( f->f_sub_initial.bv_val ) { -- bv.bv_len += f->f_sub_initial.bv_len; -+ bv.bv_len += f->f_sub_initial.bv_len + backsql_val_escape( NULL, &f->f_sub_initial, NULL ); - } - if ( f->f_sub_any != NULL ) { - for ( a = 0; f->f_sub_any[ a ].bv_val != NULL; a++ ) { -- bv.bv_len += f->f_sub_any[ a ].bv_len; -+ bv.bv_len += f->f_sub_any[ a ].bv_len + backsql_val_escape( NULL, &f->f_sub_any[ a ], NULL ); - } - } - if ( f->f_sub_final.bv_val ) { -- bv.bv_len += f->f_sub_final.bv_len; -+ bv.bv_len += f->f_sub_final.bv_len + backsql_val_escape( NULL, &f->f_sub_final, NULL ); - } - bv.bv_len = 2 * bv.bv_len - 1; - bv.bv_val = ch_malloc( bv.bv_len + 1 ); - - s = 0; - if ( !BER_BVISNULL( &f->f_sub_initial ) ) { -- bv.bv_val[ s ] = f->f_sub_initial.bv_val[ 0 ]; -- for ( i = 1; i < f->f_sub_initial.bv_len; i++ ) { -+ fvalue = &f->f_sub_initial; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; -+ bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; -+ for ( i = 1; i < fvalue->bv_len; i++ ) { - bv.bv_val[ s + 2 * i - 1 ] = '%'; -- bv.bv_val[ s + 2 * i ] = f->f_sub_initial.bv_val[ i ]; -+ bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; - } - bv.bv_val[ s + 2 * i - 1 ] = '%'; - s += 2 * i; -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - } - - if ( f->f_sub_any != NULL ) { - for ( a = 0; !BER_BVISNULL( &f->f_sub_any[ a ] ); a++ ) { -- bv.bv_val[ s ] = f->f_sub_any[ a ].bv_val[ 0 ]; -- for ( i = 1; i < f->f_sub_any[ a ].bv_len; i++ ) { -+ fvalue = &f->f_sub_any[ a ]; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; -+ bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; -+ for ( i = 1; i < fvalue->bv_len; i++ ) { - bv.bv_val[ s + 2 * i - 1 ] = '%'; -- bv.bv_val[ s + 2 * i ] = f->f_sub_any[ a ].bv_val[ i ]; -+ bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; - } - bv.bv_val[ s + 2 * i - 1 ] = '%'; - s += 2 * i; -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - } - } - - if ( !BER_BVISNULL( &f->f_sub_final ) ) { -- bv.bv_val[ s ] = f->f_sub_final.bv_val[ 0 ]; -- for ( i = 1; i < f->f_sub_final.bv_len; i++ ) { -+ fvalue = &f->f_sub_final; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; -+ bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; -+ for ( i = 1; i < fvalue->bv_len; i++ ) { - bv.bv_val[ s + 2 * i - 1 ] = '%'; -- bv.bv_val[ s + 2 * i ] = f->f_sub_final.bv_val[ i ]; -+ bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; - } -- bv.bv_val[ s + 2 * i - 1 ] = '%'; -+ bv.bv_val[ s + 2 * i - 1 ] = '%'; - s += 2 * i; -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - } - - bv.bv_val[ s - 1 ] = '\0'; -@@ -561,11 +613,17 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, - f->f_sub_initial.bv_val ); - #endif /* BACKSQL_TRACE */ - -+ fvalue = &f->f_sub_initial; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; - start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat_x( &bsi->bsi_flt_where, - bsi->bsi_op->o_tmpmemctx, - "b", -- &f->f_sub_initial ); -+ fvalue ); -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { - ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); - } -@@ -586,12 +644,18 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, - i, f->f_sub_any[ i ].bv_val ); - #endif /* BACKSQL_TRACE */ - -+ fvalue = &f->f_sub_any[ i ]; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; - start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat_x( &bsi->bsi_flt_where, - bsi->bsi_op->o_tmpmemctx, - "bc", -- &f->f_sub_any[ i ], -+ fvalue, - '%' ); -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { - /* - * Note: toupper('%') = '%' -@@ -611,11 +675,17 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, - f->f_sub_final.bv_val ); - #endif /* BACKSQL_TRACE */ - -+ fvalue = &f->f_sub_final; -+ escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); -+ if ( escaped ) -+ fvalue = &escval; - start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat_x( &bsi->bsi_flt_where, - bsi->bsi_op->o_tmpmemctx, - "b", -- &f->f_sub_final ); -+ fvalue ); -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); - if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { - ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); - } -@@ -1182,6 +1252,8 @@ backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_r - struct berval *filter_value = NULL; - MatchingRule *matching_rule = NULL; - struct berval ordering = BER_BVC("<="); -+ struct berval escval; -+ int escaped = 0; - - Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter_attr(%s)\n", - at->bam_ad->ad_cname.bv_val ); -@@ -1236,6 +1308,10 @@ equality_match:; - casefold = 1; - } - -+ escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); -+ if ( escaped ) -+ filter_value = &escval; -+ - /* FIXME: directoryString filtering should use a similar - * approach to deal with non-prettified values like - * " A non prettified value ", by using a LIKE -@@ -1316,6 +1392,10 @@ equality_match:; - casefold = 1; - } - -+ escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); -+ if ( escaped ) -+ filter_value = &escval; -+ - /* - * FIXME: should we uppercase the operands? - */ -@@ -1349,7 +1429,7 @@ equality_match:; - &at->bam_sel_expr, - &ordering, - '\'', -- &f->f_av_value, -+ filter_value, - (ber_len_t)STRLENOF( /* (' */ "')" ), - /* ( */ "')" ); - } -@@ -1373,13 +1453,17 @@ equality_match:; - case LDAP_FILTER_APPROX: - /* we do our best */ - -+ filter_value = &f->f_av_value; -+ escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); -+ if ( escaped ) -+ filter_value = &escval; - /* - * maybe we should check type of at->sel_expr here somehow, - * to know whether upper_func is applicable, but for now - * upper_func stuff is made for Oracle, where UPPER is - * safely applicable to NUMBER etc. - */ -- (void)backsql_process_filter_like( bsi, at, 1, &f->f_av_value ); -+ (void)backsql_process_filter_like( bsi, at, 1, filter_value ); - break; - - default: -@@ -1393,6 +1477,9 @@ equality_match:; - - } - -+ if ( escaped ) -+ bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); -+ - Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter_attr(%s)\n", - at->bam_ad->ad_cname.bv_val ); - --- -GitLab - diff -Nru openldap-2.5.11+dfsg/debian/patches/series openldap-2.5.12+dfsg/debian/patches/series --- openldap-2.5.11+dfsg/debian/patches/series 2022-05-12 13:07:35.000000000 +0000 +++ openldap-2.5.12+dfsg/debian/patches/series 2022-06-13 17:19:52.000000000 +0000 @@ -13,4 +13,3 @@ fix-build-top-mk switch-to-lt_dlopenadvise-to-get-RTLD_GLOBAL-set.diff set-maintainer-name -CVE-2022-29155.patch diff -Nru openldap-2.5.11+dfsg/doc/guide/admin/guide.html openldap-2.5.12+dfsg/doc/guide/admin/guide.html --- openldap-2.5.11+dfsg/doc/guide/admin/guide.html 2022-01-20 19:25:19.000000000 +0000 +++ openldap-2.5.12+dfsg/doc/guide/admin/guide.html 2022-05-04 15:54:39.000000000 +0000 @@ -23,7 +23,7 @@

OpenLDAP Software 2.5 Administrator's Guide

The OpenLDAP Project <https://www.openldap.org/>
-
20 January 2022
+
4 May 2022

diff -Nru openldap-2.5.11+dfsg/doc/man/man3/ldap_get_option.3 openldap-2.5.12+dfsg/doc/man/man3/ldap_get_option.3 --- openldap-2.5.11+dfsg/doc/man/man3/ldap_get_option.3 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/doc/man/man3/ldap_get_option.3 2022-05-04 14:57:30.000000000 +0000 @@ -455,6 +455,12 @@ .B LDAP_OPT_TCP_USER_TIMEOUT Allows to configure TCP_USER_TIMEOUT in milliseconds on the connection, overriding the operating system setting. This option is OpenLDAP specific and supported only on Linux 2.6.37 or higher. +.B invalue +must be a +.BR "const unsigned int *" ; +.BR outvalue +must be an +.BR "unsigned int *" . .SH SASL OPTIONS The SASL options are OpenLDAP specific. @@ -587,6 +593,7 @@ .BR "char **" . Its content needs to be freed by the caller using .BR ldap_memfree (3). +.TP .B LDAP_OPT_X_SASL_CBINDING Sets/gets the channel-binding type to use in SASL, one of @@ -602,7 +609,6 @@ .BR outvalue must be .BR "int *" . -.TP .SH TCP OPTIONS The TCP options are OpenLDAP specific. Mainly intended for use with Linux, they may not be portable. @@ -873,6 +879,21 @@ .BR "char **" , and its contents need to be freed by the caller using .BR ldap_memfree (3). +.TP +.B LDAP_OPT_X_TLS_PEERKEY_HASH +Sets the (public) key that the application expects the peer to be using. +.B invalue +must be +.BR "const char *" +containing the base64 encoding of the expected peer's key or in the format +.B ":" +where as a TLS session is established, the library will hash the peer's key +with the provided hash algorithm and compare it with value provided and will +only allow the session to continue if they match. This happens regardless of +certificate checking strategy. The list of supported +.B hashalg +values depends on the crypto library used, check its documentation to get +a list. .SH ERRORS On success, the functions return .BR LDAP_OPT_SUCCESS , diff -Nru openldap-2.5.11+dfsg/doc/man/man5/slapd.conf.5 openldap-2.5.12+dfsg/doc/man/man5/slapd.conf.5 --- openldap-2.5.11+dfsg/doc/man/man5/slapd.conf.5 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/doc/man/man5/slapd.conf.5 2022-05-04 14:57:30.000000000 +0000 @@ -1877,9 +1877,8 @@ accept "unlimited" and positive integers, and both default to "unlimited". The \fBsizelimit\fP and \fBtimelimit\fP parameters define a consumer requested limitation on the number of entries that can be returned -by the LDAP Content Synchronization operation; as such, it is intended -to implement partial replication based on the size of the replicated database -and on the time required by the synchronization. +by the LDAP Content Synchronization operation; these should be left unchanged +from the default otherwise replication may never succeed. Note, however, that any provider-side limits for the replication identity will be enforced by the provider regardless of the limits requested by the LDAP Content Synchronization operation, much like for any other diff -Nru openldap-2.5.11+dfsg/doc/man/man5/slapd-config.5 openldap-2.5.12+dfsg/doc/man/man5/slapd-config.5 --- openldap-2.5.11+dfsg/doc/man/man5/slapd-config.5 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/doc/man/man5/slapd-config.5 2022-05-04 14:57:30.000000000 +0000 @@ -1945,9 +1945,8 @@ accept "unlimited" and positive integers, and both default to "unlimited". The \fBsizelimit\fP and \fBtimelimit\fP parameters define a consumer requested limitation on the number of entries that can be returned -by the LDAP Content Synchronization operation; as such, it is intended -to implement partial replication based on the size of the replicated database -and on the time required by the synchronization. +by the LDAP Content Synchronization operation; these should be left unchanged +from the default otherwise replication may never succeed. Note, however, that any provider-side limits for the replication identity will be enforced by the provider regardless of the limits requested by the LDAP Content Synchronization operation, much like for any other diff -Nru openldap-2.5.11+dfsg/include/ldap_pvt.h openldap-2.5.12+dfsg/include/ldap_pvt.h --- openldap-2.5.11+dfsg/include/ldap_pvt.h 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/include/ldap_pvt.h 2022-05-04 14:57:30.000000000 +0000 @@ -185,11 +185,11 @@ #define LDAP_IPADDRLEN sizeof("IP=255.255.255.255:65336") #endif -typedef union Sockaddr Sockaddr; +union Sockaddr; LDAP_F (void) ldap_pvt_sockaddrstr LDAP_P(( - Sockaddr *sa, + union Sockaddr *sa, struct berval * )); diff -Nru openldap-2.5.11+dfsg/libraries/libldap/ldif.c openldap-2.5.12+dfsg/libraries/libldap/ldif.c --- openldap-2.5.11+dfsg/libraries/libldap/ldif.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/libraries/libldap/ldif.c 2022-05-04 14:57:30.000000000 +0000 @@ -796,6 +796,7 @@ * back to a previous file. (return from an include) */ while ( feof( lfp->fp )) { +pop: if ( lfp->prev ) { LDIFFP *tmp = lfp->prev; fclose( lfp->fp ); @@ -808,6 +809,10 @@ } if ( !stop ) { if ( fgets( line, sizeof( line ), lfp->fp ) == NULL ) { + if ( !found_entry && !ferror( lfp->fp ) ) { + /* ITS#9811 Reached the end looking for an entry, try again */ + goto pop; + } stop = 1; len = 0; } else { diff -Nru openldap-2.5.11+dfsg/libraries/libldap/result.c openldap-2.5.12+dfsg/libraries/libldap/result.c --- openldap-2.5.11+dfsg/libraries/libldap/result.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/libraries/libldap/result.c 2022-05-04 14:57:30.000000000 +0000 @@ -506,6 +506,16 @@ lc->lconn_ber = NULL; break; + default: + /* + * We read a BerElement that isn't LDAP or the stream has desync'd. + * In either case, anything we read from now on is probably garbage, + * just drop the connection. + */ + ber_free( ber, 1 ); + lc->lconn_ber = NULL; + /* FALLTHRU */ + case LBER_DEFAULT: fail: err = sock_errno(); @@ -521,10 +531,6 @@ } lc->lconn_status = 0; return -1; - - default: - ld->ld_errno = LDAP_LOCAL_ERROR; - return -1; } /* message id */ diff -Nru openldap-2.5.11+dfsg/libraries/libldap/tls_o.c openldap-2.5.12+dfsg/libraries/libldap/tls_o.c --- openldap-2.5.11+dfsg/libraries/libldap/tls_o.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/libraries/libldap/tls_o.c 2022-05-04 14:57:30.000000000 +0000 @@ -1026,8 +1026,12 @@ #ifndef OPENSSL_NO_MD2 md == EVP_md2() || #endif +#ifndef OPENSSL_NO_MD4 md == EVP_md4() || +#endif +#ifndef OPENSSL_NO_MD5 md == EVP_md5() || +#endif md == EVP_sha1() ) md = EVP_sha256(); diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/add.c openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/add.c --- openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/add.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/add.c 2022-05-04 14:57:30.000000000 +0000 @@ -51,6 +51,7 @@ } asyncmeta_drop_bc(mc, bc); slap_sl_mem_setctx(op->o_threadctx, op->o_tmpmemctx); + operation_counter_init( op, op->o_threadctx ); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); send_ldap_result(op, rs); return LDAP_SUCCESS; diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/config.c openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/config.c --- openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/config.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/config.c 2022-05-04 14:57:30.000000000 +0000 @@ -2405,9 +2405,11 @@ break; #endif /* SLAPD_META_CLIENT_PR */ - case LDAP_BACK_CFG_KEEPALIVE: - slap_keepalive_parse( ber_bvstrdup(c->argv[1]), - &mt->mt_tls.sb_keepalive, 0, 0, 0); + case LDAP_BACK_CFG_KEEPALIVE: { + struct berval bv; + ber_str2bv( c->argv[1], 0, 1, &bv ); + slap_keepalive_parse( &bv, &mt->mt_tls.sb_keepalive, 0, 0, 0 ); + } break; case LDAP_BACK_CFG_TCP_USER_TIMEOUT: diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/meta_result.c openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/meta_result.c --- openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/meta_result.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/meta_result.c 2022-05-04 14:57:30.000000000 +0000 @@ -650,6 +650,7 @@ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); + operation_counter_init( bc->op, ctx ); bc->bc_active++; ret = asyncmeta_send_pending_op(bc, candidate); if (ret != META_SEARCH_CANDIDATE) { @@ -699,6 +700,7 @@ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); + operation_counter_init( bc->op, ctx ); bc->rs.sr_err = bind_result->sr_err; bc->rs.sr_text = bind_result->sr_text; mc->pending_ops--; @@ -1422,6 +1424,7 @@ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); + operation_counter_init( bc->op, ctx ); op = bc->op; rs = &bc->rs; @@ -1569,6 +1572,7 @@ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); + operation_counter_init( bc->op, ctx ); if (bc->op->o_abandon) { ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_drop_bc( mc, bc); @@ -1668,12 +1672,14 @@ } if (bc->op->o_abandon ) { - /* set our memctx */ - bc->op->o_threadctx = ctx; - bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); - slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); Operation *op = bc->op; + /* set our memctx */ + op->o_threadctx = ctx; + op->o_tid = ldap_pvt_thread_pool_tid( ctx ); + slap_sl_mem_setctx(ctx, op->o_tmpmemctx); + operation_counter_init( op, ctx ); + LDAP_STAILQ_REMOVE(&mc->mc_om_list, bc, bm_context_t, bc_next); mc->pending_ops--; for (j=0; jmi_ntargets; j++) { @@ -1730,6 +1736,7 @@ bc->op->o_threadctx = ctx; bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx ); slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx); + operation_counter_init( bc->op, ctx ); if (bc->searchtime) { timeout_err = LDAP_TIMELIMIT_EXCEEDED; diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/search.c openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/search.c --- openldap-2.5.11+dfsg/servers/slapd/back-asyncmeta/search.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-asyncmeta/search.c 2022-05-04 14:57:30.000000000 +0000 @@ -58,6 +58,7 @@ } } slap_sl_mem_setctx(op->o_threadctx, op->o_tmpmemctx); + operation_counter_init( op, op->o_threadctx ); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex); send_ldap_result(op, rs); } diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-ldap/config.c openldap-2.5.12+dfsg/servers/slapd/back-ldap/config.c --- openldap-2.5.11+dfsg/servers/slapd/back-ldap/config.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-ldap/config.c 2022-05-04 14:57:30.000000000 +0000 @@ -2051,9 +2051,11 @@ } break; - case LDAP_BACK_CFG_KEEPALIVE: - slap_keepalive_parse( ber_bvstrdup(c->argv[1]), - &li->li_tls.sb_keepalive, 0, 0, 0); + case LDAP_BACK_CFG_KEEPALIVE: { + struct berval bv; + ber_str2bv( c->argv[1], 0, 1, &bv ); + slap_keepalive_parse( &bv, &li->li_tls.sb_keepalive, 0, 0, 0 ); + } break; case LDAP_BACK_CFG_TCP_USER_TIMEOUT: diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-mdb/monitor.c openldap-2.5.12+dfsg/servers/slapd/back-mdb/monitor.c --- openldap-2.5.11+dfsg/servers/slapd/back-mdb/monitor.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-mdb/monitor.c 2022-05-04 14:57:30.000000000 +0000 @@ -578,10 +578,11 @@ monitor_extra_t *mbe; if ( mi && mi->bi_extra ) { + struct berval dummy = BER_BVNULL; mbe = mi->bi_extra; mbe->unregister_entry_callback( &mdb->mi_monitor.mdm_ndn, (monitor_callback_t *)mdb->mi_monitor.mdm_cb, - NULL, 0, NULL ); + &dummy, 0, &dummy ); } memset( &mdb->mi_monitor, 0, sizeof( mdb->mi_monitor ) ); diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-meta/config.c openldap-2.5.12+dfsg/servers/slapd/back-meta/config.c --- openldap-2.5.11+dfsg/servers/slapd/back-meta/config.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-meta/config.c 2022-05-04 14:57:30.000000000 +0000 @@ -2662,7 +2662,6 @@ c->fname, c->lineno, ca.argc, ca.argv ); } assert( rc == 0 ); - ch_free( ca.argv ); ch_free( ca.tline ); } } @@ -2699,9 +2698,9 @@ c->fname, c->lineno, ca.argc, argv ); } assert( rc == 0 ); - ch_free( ca.argv ); ch_free( ca.tline ); } + ch_free( ca.argv ); } /* save the rule info */ @@ -2718,7 +2717,7 @@ /* move it to the right slot */ if ( ix < cnt ) { for ( i=cnt; i>ix; i-- ) - mt->mt_rwmap.rwm_bva_rewrite[i+1] = mt->mt_rwmap.rwm_bva_rewrite[i]; + mt->mt_rwmap.rwm_bva_rewrite[i] = mt->mt_rwmap.rwm_bva_rewrite[i-1]; mt->mt_rwmap.rwm_bva_rewrite[i] = bv; /* destroy old rules */ @@ -2730,7 +2729,7 @@ case LDAP_BACK_CFG_MAP: { /* objectclass/attribute mapping */ ConfigArgs ca = { 0 }; - char *argv[5]; + char *argv[5], **argvp; struct ldapmap rwm_oc; struct ldapmap rwm_at; int cnt = 0, ix = c->valx; @@ -2763,7 +2762,8 @@ argv[2] = ca.argv[1]; argv[3] = ca.argv[2]; argv[4] = ca.argv[3]; - ch_free( ca.argv ); + + argvp = ca.argv; ca.argv = argv; ca.argc++; rc = ldap_back_map_config( &ca, &mt->mt_rwmap.rwm_oc, @@ -2771,7 +2771,7 @@ ch_free( ca.tline ); ca.tline = NULL; - ca.argv = NULL; + ca.argv = argvp; /* in case of failure, restore * the existing mapping */ @@ -2788,7 +2788,7 @@ } if ( ix < cnt ) { - for ( ; imt_rwmap.rwm_bva_map[ i ].bv_val; ca.argc = 0; config_fp_parse_line( &ca ); @@ -2798,7 +2798,7 @@ argv[3] = ca.argv[2]; argv[4] = ca.argv[3]; - ch_free( ca.argv ); + argvp = ca.argv; ca.argv = argv; ca.argc++; rc = ldap_back_map_config( &ca, &mt->mt_rwmap.rwm_oc, @@ -2806,7 +2806,7 @@ ch_free( ca.tline ); ca.tline = NULL; - ca.argv = NULL; + ca.argv = argvp; /* in case of failure, restore * the existing mapping */ @@ -2814,6 +2814,7 @@ goto map_fail; } } + ch_free( ca.argv ); } /* save the map info */ @@ -2825,7 +2826,7 @@ /* move it to the right slot */ if ( ix < cnt ) { for ( i=cnt; i>ix; i-- ) - mt->mt_rwmap.rwm_bva_map[i+1] = mt->mt_rwmap.rwm_bva_map[i]; + mt->mt_rwmap.rwm_bva_map[i] = mt->mt_rwmap.rwm_bva_map[i-1]; mt->mt_rwmap.rwm_bva_map[i] = bv; /* destroy old mapping */ @@ -2841,6 +2842,7 @@ meta_back_map_free( &mt->mt_rwmap.rwm_at ); mt->mt_rwmap.rwm_oc = rwm_oc; mt->mt_rwmap.rwm_at = rwm_at; + ch_free( ca.argv ); } } break; @@ -2913,9 +2915,11 @@ break; #endif /* SLAPD_META_CLIENT_PR */ - case LDAP_BACK_CFG_KEEPALIVE: - slap_keepalive_parse( ber_bvstrdup(c->argv[1]), - &mt->mt_tls.sb_keepalive, 0, 0, 0); + case LDAP_BACK_CFG_KEEPALIVE: { + struct berval bv; + ber_str2bv( c->argv[ 1 ], 0, 1, &bv ); + slap_keepalive_parse( &bv, &mt->mt_tls.sb_keepalive, 0, 0, 0 ); + } break; case LDAP_BACK_CFG_TCP_USER_TIMEOUT: diff -Nru openldap-2.5.11+dfsg/servers/slapd/back-sql/search.c openldap-2.5.12+dfsg/servers/slapd/back-sql/search.c --- openldap-2.5.11+dfsg/servers/slapd/back-sql/search.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/back-sql/search.c 2022-05-04 14:57:30.000000000 +0000 @@ -63,6 +63,38 @@ ID *lastid ); #endif /* ! BACKSQL_ARBITRARY_KEY */ +/* Look for chars that need to be escaped, return count of them. + * If out is non-NULL, copy escape'd val to it. + */ +static int +backsql_val_escape( Operation *op, struct berval *in, struct berval *out ) +{ + char *ptr, *end; + int q = 0; + + ptr = in->bv_val; + end = ptr + in->bv_len; + while (ptr < end) { + if ( *ptr == '\'' ) + q++; + ptr++; + } + if ( q && out ) { + char *dst; + out->bv_len = in->bv_len + q; + out->bv_val = op->o_tmpalloc( out->bv_len + 1, op->o_tmpmemctx ); + ptr = in->bv_val; + dst = out->bv_val; + while (ptr < end ) { + if ( *ptr == '\'' ) + *dst++ = '\''; + *dst++ = *ptr++; + } + *dst = '\0'; + } + return q; +} + static int backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad ) { @@ -429,6 +461,8 @@ backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; int i; int casefold = 0; + int escaped = 0; + struct berval escval, *fvalue; if ( !f ) { return 0; @@ -462,50 +496,68 @@ BER_BVZERO( &bv ); if ( f->f_sub_initial.bv_val ) { - bv.bv_len += f->f_sub_initial.bv_len; + bv.bv_len += f->f_sub_initial.bv_len + backsql_val_escape( NULL, &f->f_sub_initial, NULL ); } if ( f->f_sub_any != NULL ) { for ( a = 0; f->f_sub_any[ a ].bv_val != NULL; a++ ) { - bv.bv_len += f->f_sub_any[ a ].bv_len; + bv.bv_len += f->f_sub_any[ a ].bv_len + backsql_val_escape( NULL, &f->f_sub_any[ a ], NULL ); } } if ( f->f_sub_final.bv_val ) { - bv.bv_len += f->f_sub_final.bv_len; + bv.bv_len += f->f_sub_final.bv_len + backsql_val_escape( NULL, &f->f_sub_final, NULL ); } bv.bv_len = 2 * bv.bv_len - 1; bv.bv_val = ch_malloc( bv.bv_len + 1 ); s = 0; if ( !BER_BVISNULL( &f->f_sub_initial ) ) { - bv.bv_val[ s ] = f->f_sub_initial.bv_val[ 0 ]; - for ( i = 1; i < f->f_sub_initial.bv_len; i++ ) { + fvalue = &f->f_sub_initial; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; + bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; + for ( i = 1; i < fvalue->bv_len; i++ ) { bv.bv_val[ s + 2 * i - 1 ] = '%'; - bv.bv_val[ s + 2 * i ] = f->f_sub_initial.bv_val[ i ]; + bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; } bv.bv_val[ s + 2 * i - 1 ] = '%'; s += 2 * i; + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); } if ( f->f_sub_any != NULL ) { for ( a = 0; !BER_BVISNULL( &f->f_sub_any[ a ] ); a++ ) { - bv.bv_val[ s ] = f->f_sub_any[ a ].bv_val[ 0 ]; - for ( i = 1; i < f->f_sub_any[ a ].bv_len; i++ ) { + fvalue = &f->f_sub_any[ a ]; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; + bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; + for ( i = 1; i < fvalue->bv_len; i++ ) { bv.bv_val[ s + 2 * i - 1 ] = '%'; - bv.bv_val[ s + 2 * i ] = f->f_sub_any[ a ].bv_val[ i ]; + bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; } bv.bv_val[ s + 2 * i - 1 ] = '%'; s += 2 * i; + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); } } if ( !BER_BVISNULL( &f->f_sub_final ) ) { - bv.bv_val[ s ] = f->f_sub_final.bv_val[ 0 ]; - for ( i = 1; i < f->f_sub_final.bv_len; i++ ) { + fvalue = &f->f_sub_final; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; + bv.bv_val[ s ] = fvalue->bv_val[ 0 ]; + for ( i = 1; i < fvalue->bv_len; i++ ) { bv.bv_val[ s + 2 * i - 1 ] = '%'; - bv.bv_val[ s + 2 * i ] = f->f_sub_final.bv_val[ i ]; + bv.bv_val[ s + 2 * i ] = fvalue->bv_val[ i ]; } - bv.bv_val[ s + 2 * i - 1 ] = '%'; + bv.bv_val[ s + 2 * i - 1 ] = '%'; s += 2 * i; + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); } bv.bv_val[ s - 1 ] = '\0'; @@ -561,11 +613,17 @@ f->f_sub_initial.bv_val ); #endif /* BACKSQL_TRACE */ + fvalue = &f->f_sub_initial; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "b", - &f->f_sub_initial ); + fvalue ); + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } @@ -586,12 +644,18 @@ i, f->f_sub_any[ i ].bv_val ); #endif /* BACKSQL_TRACE */ + fvalue = &f->f_sub_any[ i ]; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "bc", - &f->f_sub_any[ i ], + fvalue, '%' ); + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { /* * Note: toupper('%') = '%' @@ -611,11 +675,17 @@ f->f_sub_final.bv_val ); #endif /* BACKSQL_TRACE */ + fvalue = &f->f_sub_final; + escaped = backsql_val_escape( bsi->bsi_op, fvalue, &escval ); + if ( escaped ) + fvalue = &escval; start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "b", - &f->f_sub_final ); + fvalue ); + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } @@ -1182,6 +1252,8 @@ struct berval *filter_value = NULL; MatchingRule *matching_rule = NULL; struct berval ordering = BER_BVC("<="); + struct berval escval; + int escaped = 0; Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter_attr(%s)\n", at->bam_ad->ad_cname.bv_val ); @@ -1236,6 +1308,10 @@ casefold = 1; } + escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); + if ( escaped ) + filter_value = &escval; + /* FIXME: directoryString filtering should use a similar * approach to deal with non-prettified values like * " A non prettified value ", by using a LIKE @@ -1316,6 +1392,10 @@ casefold = 1; } + escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); + if ( escaped ) + filter_value = &escval; + /* * FIXME: should we uppercase the operands? */ @@ -1349,7 +1429,7 @@ &at->bam_sel_expr, &ordering, '\'', - &f->f_av_value, + filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* ( */ "')" ); } @@ -1373,13 +1453,17 @@ case LDAP_FILTER_APPROX: /* we do our best */ + filter_value = &f->f_av_value; + escaped = backsql_val_escape( bsi->bsi_op, filter_value, &escval ); + if ( escaped ) + filter_value = &escval; /* * maybe we should check type of at->sel_expr here somehow, * to know whether upper_func is applicable, but for now * upper_func stuff is made for Oracle, where UPPER is * safely applicable to NUMBER etc. */ - (void)backsql_process_filter_like( bsi, at, 1, &f->f_av_value ); + (void)backsql_process_filter_like( bsi, at, 1, filter_value ); break; default: @@ -1393,6 +1477,9 @@ } + if ( escaped ) + bsi->bsi_op->o_tmpfree( escval.bv_val, bsi->bsi_op->o_tmpmemctx ); + Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter_attr(%s)\n", at->bam_ad->ad_cname.bv_val ); diff -Nru openldap-2.5.11+dfsg/servers/slapd/bconfig.c openldap-2.5.12+dfsg/servers/slapd/bconfig.c --- openldap-2.5.11+dfsg/servers/slapd/bconfig.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/bconfig.c 2022-05-04 14:57:30.000000000 +0000 @@ -75,6 +75,7 @@ BackendDB cb_db; /* underlying database */ int cb_got_ldif; int cb_use_ldif; + ldap_pvt_thread_rdwr_t cb_rwlock; } CfBackInfo; static CfBackInfo cfBackInfo; @@ -1363,7 +1364,7 @@ c->value_int = (SLAP_NOLASTMOD(c->be) == 0); break; case CFG_LASTBIND: - c->value_int = (SLAP_NOLASTMOD(c->be) == 0); + c->value_int = (SLAP_LASTBIND(c->be) != 0); break; case CFG_SYNC_SUBENTRY: c->value_int = (SLAP_SYNC_SUBENTRY(c->be) != 0); @@ -5959,6 +5960,8 @@ if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + /* Strategy: * 1) check for existence of entry * 2) check for sibling renumbering @@ -6007,6 +6010,7 @@ } out2:; + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( dopause ) slap_unpause_server(); @@ -6493,6 +6497,7 @@ if ( slap_pause_server() < 0 ) do_pause = 0; } + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); /* Strategy: * 1) perform the Modify on the cached Entry. @@ -6524,6 +6529,7 @@ op->o_ndn = ndn; } + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( do_pause ) slap_unpause_server(); out: @@ -6663,6 +6669,8 @@ if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + if ( ce->ce_type == Cft_Schema ) { req_modrdn_s modr = op->oq_modrdn; struct berval rdn; @@ -6727,6 +6735,8 @@ op->oq_modrdn = modr; } + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); + if ( dopause ) slap_unpause_server(); out: @@ -6762,6 +6772,8 @@ if ( slap_pause_server() < 0 ) dopause = 0; + ldap_pvt_thread_rdwr_wlock( &cfb->cb_rwlock ); + if ( ce->ce_type == Cft_Overlay ){ overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi, op ); } else if ( ce->ce_type == Cft_Misc ) { @@ -6780,8 +6792,7 @@ if ( !oc_at ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "objectclass not found"; - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } for ( i=0; !BER_BVISNULL(&oc_at->a_nvals[i]); i++ ) { co.co_name = &oc_at->a_nvals[i]; @@ -6798,8 +6809,7 @@ /* FIXME: We should return a helpful error message * here */ } - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } break; } @@ -6807,8 +6817,7 @@ if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){ rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "Cannot delete config or frontend database"; - if ( dopause ) slap_unpause_server(); - goto out; + goto out2; } if ( ce->ce_be->bd_info->bi_db_close ) { ce->ce_be->bd_info->bi_db_close( ce->ce_be, NULL ); @@ -6869,6 +6878,8 @@ ce->ce_entry->e_private=NULL; entry_free(ce->ce_entry); ch_free(ce); +out2: + ldap_pvt_thread_rdwr_wunlock( &cfb->cb_rwlock ); if ( dopause ) slap_unpause_server(); } else { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; @@ -6890,6 +6901,7 @@ cfb = (CfBackInfo *)op->o_bd->be_private; + ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock ); ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last ); if ( !ce ) { if ( last ) @@ -6924,6 +6936,7 @@ } out: + ldap_pvt_thread_rdwr_runlock( &cfb->cb_rwlock ); send_ldap_result( op, rs ); return rs->sr_err; } @@ -7659,6 +7672,8 @@ ch_free( cfdir.bv_val ); + ldap_pvt_thread_rdwr_destroy( &cfb->cb_rwlock ); + ldap_avl_free( CfOcTree, NULL ); if ( cfb->cb_db.bd_info ) { @@ -7693,6 +7708,8 @@ ber_dupbv( &dn, &be->be_rootdn ); ber_bvarray_add( &be->be_nsuffix, &dn ); + ldap_pvt_thread_rdwr_init( &cfb->cb_rwlock ); + /* Hide from namingContexts */ SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG; diff -Nru openldap-2.5.11+dfsg/servers/slapd/connection.c openldap-2.5.12+dfsg/servers/slapd/connection.c --- openldap-2.5.11+dfsg/servers/slapd/connection.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/connection.c 2022-05-04 14:57:30.000000000 +0000 @@ -212,7 +212,7 @@ /* Don't timeout a slow-running request or a persistent * outbound connection. */ - if((( c->c_n_ops_executing || c->c_n_ops_async ) && !c->c_writewaiter) + if( c->c_n_ops_executing || c->c_n_ops_async || c->c_conn_state == SLAP_C_CLIENT ) { continue; } @@ -244,7 +244,7 @@ /* Don't close a slow-running request or a persistent * outbound connection. */ - if((( c->c_n_ops_executing || c->c_n_ops_async ) && !c->c_writewaiter) + if( c->c_n_ops_executing || c->c_n_ops_async || c->c_conn_state == SLAP_C_CLIENT ) { continue; } @@ -734,6 +734,7 @@ LDAP_STAILQ_NEXT(o, o_next) = NULL; slap_op_free( o, NULL ); } + c->c_n_ops_pending = 0; } static void @@ -870,13 +871,14 @@ for(; *index < dtblsize; (*index)++) { if( connections[*index].c_sb ) { - c = &connections[(*index)++]; + c = &connections[*index]; ldap_pvt_thread_mutex_lock( &c->c_mutex ); if ( c->c_conn_state == SLAP_C_INVALID ) { ldap_pvt_thread_mutex_unlock( &c->c_mutex ); c = NULL; continue; } + (*index)++; break; } } @@ -963,18 +965,18 @@ ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex ); } -static void -conn_counter_init( Operation *op, void *ctx ) +void +operation_counter_init( Operation *op, void *ctx ) { slap_counters_t *sc; void *vsc = NULL; if ( ldap_pvt_thread_pool_getkey( - ctx, (void *)conn_counter_init, &vsc, NULL ) || !vsc ) { + ctx, (void *)operation_counter_init, &vsc, NULL ) || !vsc ) { vsc = ch_malloc( sizeof( slap_counters_t )); sc = vsc; slap_counters_init( sc ); - ldap_pvt_thread_pool_setkey( ctx, (void*)conn_counter_init, vsc, + ldap_pvt_thread_pool_setkey( ctx, (void*)operation_counter_init, vsc, conn_counter_destroy, NULL, NULL ); ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex ); @@ -1030,7 +1032,7 @@ op->o_qtime.tv_sec--; } op->o_qtime.tv_sec -= op->o_time; - conn_counter_init( op, ctx ); + operation_counter_init( op, ctx ); ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); /* FIXME: returns 0 in case of failure */ ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated, 1); diff -Nru openldap-2.5.11+dfsg/servers/slapd/daemon.c openldap-2.5.12+dfsg/servers/slapd/daemon.c --- openldap-2.5.11+dfsg/servers/slapd/daemon.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/daemon.c 2022-05-04 14:57:30.000000000 +0000 @@ -2413,6 +2413,18 @@ } static void * +slapd_rtask_trampoline( + void *ctx, + void *arg ) +{ + struct re_s *rtask = arg; + + /* invalidate pool_cookie */ + rtask->pool_cookie = NULL; + return rtask->routine( ctx, arg ); +} + +static void * slapd_daemon_task( void *ptr ) { @@ -2775,7 +2787,7 @@ ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); ldap_pvt_thread_pool_submit2( &connection_pool, - rtask->routine, (void *) rtask, &rtask->pool_cookie ); + slapd_rtask_trampoline, (void *) rtask, &rtask->pool_cookie ); ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); } rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat ); diff -Nru openldap-2.5.11+dfsg/servers/slapd/overlays/dynlist.c openldap-2.5.12+dfsg/servers/slapd/overlays/dynlist.c --- openldap-2.5.11+dfsg/servers/slapd/overlays/dynlist.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/overlays/dynlist.c 2022-05-04 14:57:30.000000000 +0000 @@ -1208,13 +1208,16 @@ Filter *dnf, *orf = NULL; int i; - if ( a->a_numvals == 1 ) { + if ( a->a_numvals == 1 && n->f_choice == SLAPD_FILTER_COMPUTED ) { dnf = n; } else { orf = n; - orf->f_choice = LDAP_FILTER_OR; + if ( n->f_choice != LDAP_FILTER_OR ) { + orf->f_choice = LDAP_FILTER_OR; + orf->f_list = NULL; + } dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx ); - dnf->f_next = NULL; + dnf->f_next = orf->f_list; orf->f_list = dnf; } @@ -1298,9 +1301,9 @@ break; case LDAP_FILTER_EQUALITY: - n->f_choice = SLAPD_FILTER_COMPUTED; if ( f->f_av_desc == ad ) { dynlist_name_t *dyn = ldap_tavl_find( ds->ds_names, &f->f_av_value, dynlist_avl_cmp ); + n->f_choice = SLAPD_FILTER_COMPUTED; if ( dyn && !dynlist_filter_group( op, dyn, n, ds )) break; } diff -Nru openldap-2.5.11+dfsg/servers/slapd/overlays/pcache.c openldap-2.5.12+dfsg/servers/slapd/overlays/pcache.c --- openldap-2.5.11+dfsg/servers/slapd/overlays/pcache.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/overlays/pcache.c 2022-05-04 14:57:30.000000000 +0000 @@ -5660,15 +5660,16 @@ slap_overinst *on = (slap_overinst *)be->bd_info; cache_manager *cm = on->on_bi.bi_private; - if ( cm->monitor_cb != NULL ) { + if ( !BER_BVISNULL( &cm->monitor_ndn )) { BackendInfo *mi = backend_info( "monitor" ); monitor_extra_t *mbe; if ( mi && mi->bi_extra ) { + struct berval dummy = BER_BVNULL; mbe = mi->bi_extra; mbe->unregister_entry_callback( &cm->monitor_ndn, (monitor_callback_t *)cm->monitor_cb, - NULL, 0, NULL ); + &dummy, 0, &dummy ); } } diff -Nru openldap-2.5.11+dfsg/servers/slapd/overlays/ppolicy.c openldap-2.5.12+dfsg/servers/slapd/overlays/ppolicy.c --- openldap-2.5.11+dfsg/servers/slapd/overlays/ppolicy.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/overlays/ppolicy.c 2022-05-04 14:57:30.000000000 +0000 @@ -2215,6 +2215,7 @@ PassPolicy pp; Attribute *pa; const char *txt; + int is_pwdadmin = 0; if ( ppolicy_restrict( op, rs ) != SLAP_CB_CONTINUE ) return rs->sr_err; @@ -2223,10 +2224,14 @@ if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) ) return SLAP_CB_CONTINUE; + ppolicy_get( op, op->ora_e, &pp ); + + if ( access_allowed( op, op->ora_e, pp.ad, NULL, ACL_MANAGE, NULL ) ) { + is_pwdadmin = 1; + } + /* Check for password in entry */ - if ((pa = attr_find( op->oq_add.rs_e->e_attrs, - slap_schema.si_ad_userPassword ))) - { + if ( (pa = attr_find( op->oq_add.rs_e->e_attrs, pp.ad )) ) { assert( pa->a_vals != NULL ); assert( !BER_BVISNULL( &pa->a_vals[ 0 ] ) ); @@ -2235,15 +2240,13 @@ return rs->sr_err; } - ppolicy_get( op, op->ora_e, &pp ); - /* - * new entry contains a password - if we're not the root user + * new entry contains a password - if we're not the password admin * then we need to check that the password fits in with the * security policy for the new entry. */ - if (pp.pwdCheckQuality > 0 && !be_isroot( op )) { + if ( pp.pwdCheckQuality > 0 && !is_pwdadmin ) { struct berval *bv = &(pa->a_vals[0]); int rc, send_ctrl = 0; LDAPPasswordPolicyError pErr = PP_noError; @@ -2305,7 +2308,8 @@ } /* If password aging is in effect, set the pwdChangedTime */ - if ( pp.pwdMaxAge || pp.pwdMinAge ) { + if ( ( pp.pwdMaxAge || pp.pwdMinAge ) && + !attr_find( op->ora_e->e_attrs, ad_pwdChangedTime ) ) { struct berval timestamp; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; time_t now = slap_get_time(); diff -Nru openldap-2.5.11+dfsg/servers/slapd/overlays/syncprov.c openldap-2.5.12+dfsg/servers/slapd/overlays/syncprov.c --- openldap-2.5.11+dfsg/servers/slapd/overlays/syncprov.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/overlays/syncprov.c 2022-05-04 14:57:30.000000000 +0000 @@ -1075,6 +1075,7 @@ op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx, 1); op->o_tmpmfuncs = &slap_sl_mfuncs; op->o_threadctx = ctx; + operation_counter_init( op, ctx ); /* syncprov_qplay expects a fake db */ be = *so->s_op->o_bd; diff -Nru openldap-2.5.11+dfsg/servers/slapd/overlays/translucent.c openldap-2.5.12+dfsg/servers/slapd/overlays/translucent.c --- openldap-2.5.11+dfsg/servers/slapd/overlays/translucent.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/overlays/translucent.c 2022-05-04 14:57:30.000000000 +0000 @@ -999,7 +999,6 @@ case LDAP_FILTER_GE: case LDAP_FILTER_LE: case LDAP_FILTER_APPROX: - case LDAP_FILTER_SUBSTRINGS: case LDAP_FILTER_EXT: if ( !f->f_av_desc || ad_inlist( f->f_av_desc, an )) { AttributeAssertion *nava; @@ -1015,6 +1014,29 @@ n->f_next = NULL; } break; + + case LDAP_FILTER_SUBSTRINGS: + if ( !f->f_av_desc || ad_inlist( f->f_av_desc, an )) { + SubstringsAssertion *nsub; + + n = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx ); + n->f_choice = f->f_choice; + + nsub = op->o_tmpalloc( sizeof(SubstringsAssertion), op->o_tmpmemctx ); + *nsub = *f->f_sub; + n->f_sub = nsub; + + if ( !BER_BVISNULL( &f->f_sub_initial )) + ber_dupbv_x( &n->f_sub_initial, &f->f_sub_initial, op->o_tmpmemctx ); + + ber_bvarray_dup_x( &n->f_sub_any, f->f_sub_any, op->o_tmpmemctx ); + + if ( !BER_BVISNULL( &f->f_sub_final )) + ber_dupbv_x( &n->f_sub_final, &f->f_sub_final, op->o_tmpmemctx ); + + n->f_next = NULL; + } + break; case LDAP_FILTER_AND: case LDAP_FILTER_OR: diff -Nru openldap-2.5.11+dfsg/servers/slapd/proto-slap.h openldap-2.5.12+dfsg/servers/slapd/proto-slap.h --- openldap-2.5.11+dfsg/servers/slapd/proto-slap.h 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/proto-slap.h 2022-05-04 14:57:30.000000000 +0000 @@ -800,6 +800,7 @@ struct berval *id LDAP_PF_LOCAL_SENDMSG_ARG(struct berval *peerbv))); +LDAP_SLAPD_F (void) operation_counter_init LDAP_P(( Operation *op, void *threadctx )); LDAP_SLAPD_F (void) connection_closing LDAP_P(( Connection *c, const char *why )); LDAP_SLAPD_F (int) connection_is_active LDAP_P(( ber_socket_t s )); diff -Nru openldap-2.5.11+dfsg/servers/slapd/syncrepl.c openldap-2.5.12+dfsg/servers/slapd/syncrepl.c --- openldap-2.5.11+dfsg/servers/slapd/syncrepl.c 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/servers/slapd/syncrepl.c 2022-05-04 14:57:30.000000000 +0000 @@ -58,6 +58,8 @@ #define UUIDLEN 16 +struct syncinfo_s; + struct nonpresent_entry { struct berval *npe_name; struct berval *npe_nname; @@ -85,8 +87,19 @@ struct berval *cs_pvals; int *cs_psids; int cs_pnum; + + /* serialize multi-consumer refreshes */ + ldap_pvt_thread_mutex_t cs_refresh_mutex; + struct syncinfo_s *cs_refreshing; } cookie_state; +#define SYNC_TIMEOUT 0 +#define SYNC_SHUTDOWN -100 +#define SYNC_ERROR -101 +#define SYNC_REPOLL -102 +#define SYNC_PAUSED -103 +#define SYNC_BUSY -104 + #define SYNCDATA_DEFAULT 0 /* entries are plain LDAP entries */ #define SYNCDATA_ACCESSLOG 1 /* entries are accesslog format */ #define SYNCDATA_CHANGELOG 2 /* entries are changelog format */ @@ -139,6 +152,7 @@ int si_refreshDelete; int si_refreshPresent; int si_refreshDone; + int si_paused; int si_syncdata; int si_logstate; int si_lazyCommit; @@ -488,6 +502,64 @@ si->si_exattrs = exattrs; } +static int +start_refresh(syncinfo_t *si) +{ + ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_refresh_mutex ); + if ( si->si_cookieState->cs_refreshing ) { + struct re_s* rtask = si->si_re; + + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); + ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + + si->si_paused = 1; + Debug( LDAP_DEBUG_SYNC, "start_refresh: %s " + "a refresh on %s in progress, pausing\n", + si->si_ridtxt, si->si_cookieState->cs_refreshing->si_ridtxt ); + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_refresh_mutex ); + return SYNC_BUSY; + } + si->si_cookieState->cs_refreshing = si; + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_refresh_mutex ); + + return LDAP_SUCCESS; +} + +static int +refresh_finished(syncinfo_t *si) +{ + syncinfo_t *sie; + int removed = 0; + + ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_refresh_mutex ); + if ( si->si_cookieState->cs_refreshing == si ) { + si->si_cookieState->cs_refreshing = NULL; + removed = 1; + } + + if ( removed ) { + for ( sie = si->si_be->be_syncinfo; sie; sie = sie->si_next ) { + if ( sie->si_paused ) { + struct re_s* rtask = sie->si_re; + + Debug( LDAP_DEBUG_SYNC, "refresh_finished: %s " + "rescheduling refresh on %s\n", + si->si_ridtxt, sie->si_ridtxt ); + sie->si_paused = 0; + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); + rtask->interval.tv_sec = 0; + ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); + rtask->interval.tv_sec = si->si_interval; + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + break; + } + } + } + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_refresh_mutex ); + return removed; +} + static struct berval generic_filterstr = BER_BVC("(objectclass=*)"); static int @@ -511,6 +583,8 @@ ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx ); + si->si_msgid = 0; + /* If we're using a log but we have no state, then fallback to * normal mode for a full refresh. */ @@ -519,6 +593,11 @@ LDAPMessage *res, *msg; unsigned long first = 0, last = 0; int gotfirst = 0, gotlast = 0; + + if ( (rc = start_refresh( si )) ) { + return rc; + } + /* See if we're new enough for the remote server */ lattrs[0] = "firstchangenumber"; lattrs[1] = "lastchangenumber"; @@ -597,6 +676,10 @@ attrs = lattrs; attrsonly = 0; } else { + if ( (rc = start_refresh( si )) ) { + return rc; + } + rhint = 1; base = si->si_base.bv_val; filter = si->si_filterstr.bv_val; @@ -680,6 +763,10 @@ } } + si->si_refreshDone = 0; + si->si_refreshPresent = 0; + si->si_refreshDelete = 0; + rc = ldap_search_ext( si->si_ld, base, scope, filter, attrs, attrsonly, ctrls, NULL, NULL, si->si_slimit, &si->si_msgid ); ber_free_buf( ber ); @@ -929,7 +1016,6 @@ #endif si->si_lastconnect = slap_get_time(); - si->si_refreshDone = 0; rc = slap_client_connect( &si->si_ld, &si->si_bindconf ); if ( rc != LDAP_SUCCESS ) { goto done; @@ -1095,7 +1181,10 @@ rc = ldap_sync_search( si, op->o_tmpmemctx ); - if( rc != LDAP_SUCCESS ) { + if ( rc == SYNC_BUSY ) { + return rc; + } else if ( rc != LDAP_SUCCESS ) { + refresh_finished( si ); Debug( LDAP_DEBUG_ANY, "do_syncrep1: %s " "ldap_search_ext: %s (%d)\n", si->si_ridtxt, ldap_err2string( rc ), rc ); @@ -1187,12 +1276,6 @@ return rc; } -#define SYNC_TIMEOUT 0 -#define SYNC_SHUTDOWN -100 -#define SYNC_ERROR -101 -#define SYNC_REPOLL -102 -#define SYNC_PAUSED -103 - static int get_pmutex( syncinfo_t *si @@ -1236,6 +1319,8 @@ struct timeval tout = { 0, 0 }; int refreshDeletes = 0; + int refreshing = !si->si_refreshDone && + !( si->si_syncdata && si->si_logstate == SYNCLOG_LOGGING ); char empty[6] = "empty"; if ( slapd_shutdown ) { @@ -1291,6 +1376,7 @@ break; } #endif + punlock = -1; ldap_get_entry_controls( si->si_ld, msg, &rctrls ); ldap_get_dn_ber( si->si_ld, msg, NULL, &bdn ); if (!bdn.bv_len) { @@ -1307,8 +1393,6 @@ /* The notification control is only sent during persist phase */ rctrlp = ldap_control_find( LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE, rctrls, &next ); if ( rctrlp ) { - if ( !si->si_refreshDone ) - si->si_refreshDone = 1; if ( si->si_refreshDone ) syncrepl_dsee_update( si, op ); } @@ -1380,7 +1464,6 @@ rc = -1; goto done; } - punlock = -1; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, /*"{"*/ "m}", &cookie ) != LBER_ERROR ) { @@ -1716,6 +1799,14 @@ "LDAP_RES_INTERMEDIATE", si_tag == LDAP_TAG_SYNC_REFRESH_PRESENT ? "REFRESH_PRESENT" : "REFRESH_DELETE" ); + if ( si->si_refreshDone ) { + Debug( LDAP_DEBUG_ANY, "do_syncrep2: %s " + "server sent multiple refreshDone " + "messages? Ending session\n", + si->si_ridtxt ); + rc = LDAP_PROTOCOL_ERROR; + goto done; + } if ( si_tag == LDAP_TAG_SYNC_REFRESH_DELETE ) { si->si_refreshDelete = 1; } else { @@ -1754,9 +1845,9 @@ si->si_refreshDone = 1; } ber_scanf( ber, /*"{"*/ "}" ); - if ( si->si_refreshDone ) { - Debug( LDAP_DEBUG_SYNC, "do_syncrep1: %s finished refresh\n", - si->si_ridtxt ); + if ( refreshing && si->si_refreshDone ) { + refresh_finished( si ); + refreshing = 0; } break; case LDAP_TAG_SYNC_ID_SET: @@ -1903,6 +1994,9 @@ "do_syncrep2: %s (%d) %s\n", si->si_ridtxt, err, ldap_err2string( err ) ); } + if ( refreshing && ( rc || si->si_refreshDone ) ) { + refresh_finished( si ); + } slap_sync_cookie_free( &syncCookie, 0 ); slap_sync_cookie_free( &syncCookie_req, 0 ); @@ -2041,9 +2135,6 @@ /* Establish session, do search */ if ( !si->si_ld ) { - si->si_refreshDelete = 0; - si->si_refreshPresent = 0; - if ( si->si_presentlist ) { presentlist_free( si->si_presentlist ); si->si_presentlist = NULL; @@ -2054,6 +2145,13 @@ op->o_dn = op->o_bd->be_rootdn; op->o_ndn = op->o_bd->be_rootndn; rc = do_syncrep1( op, si ); + } else if ( !si->si_msgid ) { + /* We got a SYNC_BUSY, now told to resume */ + rc = ldap_sync_search( si, op->o_tmpmemctx ); + } + if ( rc == SYNC_BUSY ) { + ldap_pvt_thread_mutex_unlock( &si->si_mutex ); + return NULL; } reload: @@ -6007,6 +6105,9 @@ ch_free( npe ); } if ( sie->si_cookieState ) { + /* Could be called from do_syncrepl (server unpaused) */ + refresh_finished( sie ); + sie->si_cookieState->cs_ref--; if ( !sie->si_cookieState->cs_ref ) { ch_free( sie->si_cookieState->cs_sids ); @@ -6016,6 +6117,8 @@ ch_free( sie->si_cookieState->cs_psids ); ber_bvarray_free( sie->si_cookieState->cs_pvals ); ldap_pvt_thread_mutex_destroy( &sie->si_cookieState->cs_pmutex ); + ldap_pvt_thread_mutex_destroy( &sie->si_cookieState->cs_refresh_mutex ); + assert( sie->si_cookieState->cs_refreshing == NULL ); ch_free( sie->si_cookieState ); } } @@ -7231,6 +7334,7 @@ si->si_cookieState = ch_calloc( 1, sizeof( cookie_state )); ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_mutex ); ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_pmutex ); + ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_refresh_mutex ); ldap_pvt_thread_cond_init( &si->si_cookieState->cs_cond ); c->be->be_syncinfo = si; @@ -7489,7 +7593,7 @@ ldap_pvt_runqueue_stoptask( &slapd_rq, re ); isrunning = 1; } - if ( ldap_pvt_thread_pool_retract( re->pool_cookie ) > 0 ) + if ( !re->pool_cookie || ldap_pvt_thread_pool_retract( re->pool_cookie ) > 0 ) isrunning = 0; ldap_pvt_runqueue_remove( &slapd_rq, re ); diff -Nru openldap-2.5.11+dfsg/tests/data/dynlist.out openldap-2.5.12+dfsg/tests/data/dynlist.out --- openldap-2.5.11+dfsg/tests/data/dynlist.out 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/tests/data/dynlist.out 2022-05-04 14:57:30.000000000 +0000 @@ -679,6 +679,10 @@ memberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com memberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com +dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example + ,dc=com +uid: jjones + # Testing negated filtered memberOf functionality... dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example, dc=com diff -Nru openldap-2.5.11+dfsg/tests/scripts/test034-translucent openldap-2.5.12+dfsg/tests/scripts/test034-translucent --- openldap-2.5.11+dfsg/tests/scripts/test034-translucent 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/tests/scripts/test034-translucent 2022-05-04 14:57:30.000000000 +0000 @@ -755,6 +755,14 @@ exit 1 fi +$LDAPSEARCH -H $URI2 -b "o=translucent" "(employeeType=consult*)" > $SEARCHOUT 2>&1 +ATTR=`grep dn: $SEARCHOUT` > $NOWHERE 2>&1 +if test -z "$ATTR" ; then + echo "got no result, should have found entry" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 1 +fi + echo "Testing search: unconfigured remote filter..." $LDAPSEARCH -H $URI2 -b "o=translucent" "(|(employeeType=foo)(carlicense=right))" > $SEARCHOUT 2>&1 diff -Nru openldap-2.5.11+dfsg/tests/scripts/test044-dynlist openldap-2.5.12+dfsg/tests/scripts/test044-dynlist --- openldap-2.5.11+dfsg/tests/scripts/test044-dynlist 2022-01-20 18:48:23.000000000 +0000 +++ openldap-2.5.12+dfsg/tests/scripts/test044-dynlist 2022-05-04 14:57:30.000000000 +0000 @@ -1049,6 +1049,17 @@ exit $RC fi +$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \ + -D "$BABSDN" -w bjensen \ + "(&(uid=jjones)(memberOf=cn=jjs,ou=groups,$BASEDN))" 'uid' \ + >> $SEARCHOUT 2>&1 +RC=$? +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + echo "Testing negated filtered memberOf functionality..." echo "# Testing negated filtered memberOf functionality..." >> $SEARCHOUT