[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1106605: unblock: openldap/2.6.10+dfsg-1 (pre-approval)



Control: tags -1 confirmed

On 2025-05-26 20:08:43 -0700, Ryan Tandy wrote:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@packages.debian.org
> Usertags: unblock
> X-Debbugs-Cc: pkg-openldap-devel@lists.alioth.debian.org
> Control: affects -1 src:openldap
> 
> For OpenLDAP in trixie, I would like to try following upstream's 2.6 LTS 
> release series.

Please go ahead.

Cheers

> 
> Ubuntu have been doing this for a couple of years already, starting with 
> the 2.5 LTS series, without regrets as far as I know.
> 
> - Policy: https://wiki.ubuntu.com/OpenLDAPUpdates
> - Recent upload (2.5.19): https://bugs.launchpad.net/bugs/2085192
> 
> The OpenLDAP release manager reviews each change and decides which 
> changes to backport to stable releases. The release policy is slightly 
> less strict than Debian: stable releases are frozen to significant 
> features and compatibility breaks, but can include minor fixes or 
> additions if they are judged to be low risk.
> 
> The full release policy is here:
> https://lists.openldap.org/hyperkitty/list/openldap-announce@openldap.org/thread/2QQNVWPUUG54JM7FGQHMMF3H4KS2PPKQ/
> 
> Upstream developers are active and react quickly to actionable 
> regression reports. The release manager is subscribed to the 
> pkg-openldap-devel mailing list and reads our bug reports.
> 
> Upstream QA includes:
> 
> - an extensive functional test suite
> - a regression test suite (relatively new, but growing)
> - upcoming releases are pre-announced and tested by the community before 
>   release
> 
> On the Debian side:
> 
> - the functional test suite is run during build
> - the regression suite is not (because the build time is already long)
> - the package has only superficial autopkgtests, consisting of a few 
>   smoke tests and regression tests
> - reverse dependencies' autopkgtests contribute more coverage
> 
> The client library (libldap) is installed on most Debian systems, but it 
> is mature and doesn't change much. The server (slapd) has most of the 
> development activity, but fewer users.
> 
> The debdiff for the 2.6.10 update is attached.
> 
> Thank you for considering,
> Ryan

> diff -Nru openldap-2.6.9+dfsg/CHANGES openldap-2.6.10+dfsg/CHANGES
> --- openldap-2.6.9+dfsg/CHANGES	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/CHANGES	2025-05-22 10:56:21.000000000 -0700
> @@ -1,5 +1,32 @@
>  OpenLDAP 2.6 Change Log
>  
> +OpenLDAP 2.6.10 Release (2025/05/22)
> +	Added slapd microsecond timestamp format for local logging (ITS#10140)
> +	Fixed libldap ldap_result behavior with LDAP_MSG_RECEIVED (ITS#10229)
> +	Fixed lloadd handling of starttls critical (ITS#10323)
> +	Fixed slapd syncrepl when used with slapo-rwm (ITS#10290)
> +	Fixed slapd regression with certain searches (ITS#10307)
> +	Fixed slapo-autoca olcAutoCAserverClass object (ITS#10288)
> +	Fixed slapo-pcache caching behaviors (ITS#10270)
> +	Minor Cleanup
> +		ITS#7080
> +		ITS#7249
> +		ITS#9934
> +		ITS#10020
> +		ITS#10168
> +		ITS#10226
> +		ITS#10279
> +		ITS#10299
> +		ITS#10302
> +		ITS#10309
> +		ITS#10312
> +		ITS#10320
> +		ITS#10325
> +		ITS#10327
> +		ITS#10328
> +		ITS#10331
> +		ITS#10336
> +
>  OpenLDAP 2.6.9 Release (2024/11/26)
>  	Fixed libldap TLS connection timeout handling (ITS#8047)
>  	Fixed libldap GnuTLS incompatible pointer type (ITS#10253)
> diff -Nru openldap-2.6.9+dfsg/build/version.var openldap-2.6.10+dfsg/build/version.var
> --- openldap-2.6.9+dfsg/build/version.var	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/build/version.var	2025-05-22 10:56:21.000000000 -0700
> @@ -15,9 +15,9 @@
>  ol_package=OpenLDAP
>  ol_major=2
>  ol_minor=6
> -ol_patch=9
> -ol_api_inc=20609
> +ol_patch=10
> +ol_api_inc=20610
>  ol_api_current=2
>  ol_api_revision=200
>  ol_api_age=0
> -ol_release_date="2024/11/26"
> +ol_release_date="2025/05/22"
> diff -Nru openldap-2.6.9+dfsg/clients/tools/common.c openldap-2.6.10+dfsg/clients/tools/common.c
> --- openldap-2.6.9+dfsg/clients/tools/common.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/clients/tools/common.c	2025-05-22 10:56:21.000000000 -0700
> @@ -780,6 +780,9 @@
>  				exit( EXIT_FAILURE );
>  			}
>  			ldapuri = ber_strdup( optarg );
> +			if ( ldapuri == NULL ) {
> +				exit( EXIT_FAILURE );
> +			}
>  			break;
>  		case 'I':
>  #ifdef HAVE_CYRUS_SASL
> @@ -980,6 +983,9 @@
>  			break;
>  		case 'w':	/* password */
>  			passwd.bv_val = ber_strdup( optarg );
> +			if ( passwd.bv_val == NULL ) {
> +				exit( EXIT_FAILURE );
> +			}
>  			{
>  				char* p;
>  
> @@ -1166,6 +1172,7 @@
>  	LDAP *ld = NULL;
>  
>  	if ( debug ) {
> +#ifdef LDAP_DEBUG
>  		if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug )
>  			!= LBER_OPT_SUCCESS )
>  		{
> @@ -1178,6 +1185,10 @@
>  			fprintf( stderr,
>  				"Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
>  		}
> +#else /* !LDAP_DEBUG */
> +		fprintf( stderr,
> +				"Must compile with LDAP_DEBUG for debugging\n", prog );
> +#endif /* !LDAP_DEBUG */
>  	}
>  
>  #ifdef SIGPIPE
> @@ -1476,6 +1487,9 @@
>  				tool_exit( ld, EXIT_FAILURE );
>  			}
>  			passwd.bv_val = ber_strdup( pw );
> +			if ( passwd.bv_val == NULL ) {
> +				tool_exit( ld, EXIT_FAILURE );
> +			}
>  			passwd.bv_len = strlen( passwd.bv_val );
>  		}
>  	}
> diff -Nru openldap-2.6.9+dfsg/clients/tools/ldapvc.c openldap-2.6.10+dfsg/clients/tools/ldapvc.c
> --- openldap-2.6.9+dfsg/clients/tools/ldapvc.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/clients/tools/ldapvc.c	2025-05-22 10:56:21.000000000 -0700
> @@ -165,6 +165,9 @@
>  			}
>  
>  			vc_sasl_mech = ber_strdup(cvalue);
> +			if (vc_sasl_mech == NULL) {
> +				exit(EXIT_FAILURE);
> +			}
>  #else
>  #endif
>  
> @@ -182,6 +185,9 @@
>  			}
>  
>  			vc_sasl_realm = ber_strdup(cvalue);
> +			if (vc_sasl_realm == NULL) {
> +				exit(EXIT_FAILURE);
> +			}
>  #else
>  			fprintf(stderr,
>  				_("%s: not compiled with SASL support\n"), prog);
> @@ -202,6 +208,9 @@
>  			}
>  
>  			vc_sasl_authcid = ber_strdup(cvalue);
> +			if (vc_sasl_authcid == NULL) {
> +				exit(EXIT_FAILURE);
> +			}
>  #else
>  			fprintf(stderr,
>  				_("%s: not compiled with SASL support\n"), prog);
> @@ -222,6 +231,9 @@
>  			}
>  
>  			vc_sasl_authzid = ber_strdup(cvalue);
> +			if (vc_sasl_authzid == NULL) {
> +				exit(EXIT_FAILURE);
> +			}
>  #else
>  			fprintf(stderr,
>  				_("%s: not compiled with SASL support\n"), prog);
> @@ -242,6 +254,9 @@
>  			}
>  
>  			vc_sasl_secprops = ber_strdup(cvalue);
> +			if (vc_sasl_secprops == NULL) {
> +				exit(EXIT_FAILURE);
> +			}
>  #else
>  			fprintf(stderr,
>  				_("%s: not compiled with SASL support\n"), prog);
> diff -Nru openldap-2.6.9+dfsg/contrib/slapd-modules/autogroup/autogroup.c openldap-2.6.10+dfsg/contrib/slapd-modules/autogroup/autogroup.c
> --- openldap-2.6.9+dfsg/contrib/slapd-modules/autogroup/autogroup.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/contrib/slapd-modules/autogroup/autogroup.c	2025-05-22 10:56:21.000000000 -0700
> @@ -529,6 +529,7 @@
>  	o.ors_attrs =  agf->agf_anlist ? agf->agf_anlist : slap_anlist_no_attrs;
>  	o.o_do_not_cache = 1;
>  	o.o_abandon = 0;
> +	o.o_managedsait = SLAP_CONTROL_NONCRITICAL;
>  
>  	agg.agg_group = age;
>  	agg.agg_filter = agf;
> @@ -2130,6 +2131,7 @@
>  	op->ors_slimit = SLAP_NO_LIMIT;
>  	op->ors_attrs =  slap_anlist_no_attrs;
>  	op->o_do_not_cache = 1;
> +	op->o_managedsait = SLAP_CONTROL_CRITICAL;
>  
>  	op->o_bd = be;
>  	op->o_bd->bd_info = (BackendInfo *)on->on_info;
> diff -Nru openldap-2.6.9+dfsg/contrib/slapd-modules/variant/variant.c openldap-2.6.10+dfsg/contrib/slapd-modules/variant/variant.c
> --- openldap-2.6.9+dfsg/contrib/slapd-modules/variant/variant.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/contrib/slapd-modules/variant/variant.c	2025-05-22 10:56:21.000000000 -0700
> @@ -696,7 +696,7 @@
>  	{ "passReplication", "on|off", 2, 2, 0,
>  		ARG_ON_OFF|ARG_OFFSET,
>  		(void *)offsetof( variant_info_t, passReplication ),
> -		"( OLcfgOvAt:9.1 NAME 'olcVariantPassReplication' "
> +		"( OLcfgCtAt:9.1 NAME 'olcVariantPassReplication' "
>  			"DESC 'Whether to let searches with replication control "
>  				"pass unmodified' "
>  			"SYNTAX OMsBoolean "
> @@ -706,7 +706,7 @@
>  	{ "variantDN", "dn", 2, 2, 0,
>  		ARG_DN|ARG_QUOTE|ARG_MAGIC,
>  		variant_set_dn,
> -		"( OLcfgOvAt:9.2 NAME 'olcVariantEntry' "
> +		"( OLcfgCtAt:9.2 NAME 'olcVariantEntry' "
>  			"DESC 'DN of the variant entry' "
>  			"EQUALITY distinguishedNameMatch "
>  			"SYNTAX OMsDN "
> @@ -716,7 +716,7 @@
>  	{ "variantRegex", "regex", 2, 2, 0,
>  		ARG_BERVAL|ARG_QUOTE|ARG_MAGIC,
>  		variant_set_regex,
> -		"( OLcfgOvAt:9.6 NAME 'olcVariantEntryRegex' "
> +		"( OLcfgCtAt:9.6 NAME 'olcVariantEntryRegex' "
>  			"DESC 'Pattern for the variant entry' "
>  			"EQUALITY caseExactMatch "
>  			"SYNTAX OMsDirectoryString "
> @@ -727,7 +727,7 @@
>  	{ "", NULL, 2, 2, 0,
>  		ARG_STRING|ARG_MAGIC|VARIANT_ATTR,
>  		variant_set_attribute,
> -		"( OLcfgOvAt:9.3 NAME 'olcVariantVariantAttribute' "
> +		"( OLcfgCtAt:9.3 NAME 'olcVariantVariantAttribute' "
>  			"DESC 'Attribute to fill in the entry' "
>  			"EQUALITY caseIgnoreMatch "
>  			"SYNTAX OMsDirectoryString "
> @@ -737,7 +737,7 @@
>  	{ "", NULL, 2, 2, 0,
>  		ARG_STRING|ARG_MAGIC|VARIANT_ATTR_ALT,
>  		variant_set_attribute,
> -		"( OLcfgOvAt:9.4 NAME 'olcVariantAlternativeAttribute' "
> +		"( OLcfgCtAt:9.4 NAME 'olcVariantAlternativeAttribute' "
>  			"DESC 'Attribute to take from the alternative entry' "
>  			"EQUALITY caseIgnoreMatch "
>  			"SYNTAX OMsDirectoryString "
> @@ -747,7 +747,7 @@
>  	{ "", NULL, 2, 2, 0,
>  		ARG_DN|ARG_QUOTE|ARG_MAGIC,
>  		variant_set_alt_dn,
> -		"( OLcfgOvAt:9.5 NAME 'olcVariantAlternativeEntry' "
> +		"( OLcfgCtAt:9.5 NAME 'olcVariantAlternativeEntry' "
>  			"DESC 'DN of the alternative entry' "
>  			"EQUALITY distinguishedNameMatch "
>  			"SYNTAX OMsDN "
> @@ -757,7 +757,7 @@
>  	{ "", NULL, 2, 2, 0,
>  		ARG_BERVAL|ARG_QUOTE|ARG_MAGIC,
>  		variant_set_alt_pattern,
> -		"( OLcfgOvAt:9.7 NAME 'olcVariantAlternativeEntryPattern' "
> +		"( OLcfgCtAt:9.7 NAME 'olcVariantAlternativeEntryPattern' "
>  			"DESC 'Replacement pattern to locate the alternative entry' "
>  			"EQUALITY caseExactMatch "
>  			"SYNTAX OMsDirectoryString "
> @@ -780,13 +780,13 @@
>  };
>  
>  static ConfigOCs variant_ocs[] = {
> -	{ "( OLcfgOvOc:9.1 "
> +	{ "( OLcfgCtOc:9.1 "
>  		"NAME 'olcVariantConfig' "
>  		"DESC 'Variant overlay configuration' "
>  		"SUP olcOverlayConfig "
>  		"MAY ( olcVariantPassReplication ) )",
>  		Cft_Overlay, variant_cfg, NULL, variant_cfadd },
> -	{ "( OLcfgOvOc:9.2 "
> +	{ "( OLcfgCtOc:9.2 "
>  		"NAME 'olcVariantVariant' "
>  		"DESC 'Variant configuration' "
>  		"MUST ( olcVariantEntry ) "
> @@ -794,7 +794,7 @@
>  		"SUP top "
>  		"STRUCTURAL )",
>  		Cft_Misc, variant_cfg, variant_ldadd },
> -	{ "( OLcfgOvOc:9.3 "
> +	{ "( OLcfgCtOc:9.3 "
>  		"NAME 'olcVariantAttribute' "
>  		"DESC 'Variant attribute description' "
>  		"MUST ( olcVariantVariantAttribute $ "
> @@ -805,7 +805,7 @@
>  		"SUP top "
>  		"STRUCTURAL )",
>  		Cft_Misc, variant_cfg, variant_attr_ldadd },
> -	{ "( OLcfgOvOc:9.4 "
> +	{ "( OLcfgCtOc:9.4 "
>  		"NAME 'olcVariantRegex' "
>  		"DESC 'Variant configuration' "
>  		"MUST ( olcVariantEntryRegex ) "
> @@ -813,7 +813,7 @@
>  		"SUP top "
>  		"STRUCTURAL )",
>  		Cft_Misc, variant_cfg, variant_regex_ldadd },
> -	{ "( OLcfgOvOc:9.5 "
> +	{ "( OLcfgCtOc:9.5 "
>  		"NAME 'olcVariantAttributePattern' "
>  		"DESC 'Variant attribute description' "
>  		"MUST ( olcVariantVariantAttribute $ "
> diff -Nru openldap-2.6.9+dfsg/debian/changelog openldap-2.6.10+dfsg/debian/changelog
> --- openldap-2.6.9+dfsg/debian/changelog	2025-03-11 16:27:52.000000000 -0700
> +++ openldap-2.6.10+dfsg/debian/changelog	2025-05-24 16:23:14.000000000 -0700
> @@ -1,3 +1,9 @@
> +openldap (2.6.10+dfsg-1) UNRELEASED; urgency=medium
> +
> +  * New upstream release.
> +
> + -- Ryan Tandy <ryan@nardis.ca>  Sat, 24 May 2025 16:23:14 -0700
> +
>  openldap (2.6.9+dfsg-2) unstable; urgency=medium
>  
>    [ Adriano Rafael Gomes ]
> diff -Nru openldap-2.6.9+dfsg/doc/guide/admin/replication.sdf openldap-2.6.10+dfsg/doc/guide/admin/replication.sdf
> --- openldap-2.6.9+dfsg/doc/guide/admin/replication.sdf	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/guide/admin/replication.sdf	2025-05-22 10:56:21.000000000 -0700
> @@ -347,6 +347,10 @@
>  bring it up to date and replication then switches back to the delta-syncrepl
>  mode.
>  
> +Note: partial replication is incompatible with deltasync. For deltasync to
> +work, the replication user needs unrestricted read access to both the main
> +database and accesslog database.
> +
>  Note: since the database state is stored in both the changelog DB and the
>  main DB on the provider, it is important to backup/restore both the changelog
>  DB and the main DB using slapcat/slapadd when restoring a DB or copying
> @@ -481,9 +485,18 @@
>  must first be configured in {{slapd.conf}}(5) before it can be
>  used. The provider has two primary configuration directives and
>  two secondary directives for when delta-syncrepl is being used.
> +
>  Because the LDAP Sync search is subject to access control, proper
>  access control privileges should be set up for the replicated
> -content.
> +content. In many environments the replicas are meant to carry the
> +same data as provider so the replication user needs unrestricted
> +read access to the database and as such this tends to be the first
> +access rule for that database:
> +
> +> access to * by "$REPLICATOR" read by * break
> +
> +However if partial replication is desired, the access rules can be
> +tightened appropriately.
>  
>  The two primary options to configure are the checkpoint and
>  sessionlog behaviors.
> @@ -497,7 +510,13 @@
>  time has passed since the last checkpoint, a new checkpoint is
>  performed. Checkpointing is disabled by default.
>  
> -The session log is configured by the
> +If an accesslog is maintained for this database and contains all the
> +successful writes, it is the preferred way to provide the resync
> +information:
> +
> +> syncprov-sessionlog-source <accesslog db suffix>
> +
> +Otherwise an in memory session session log is configured by the
>  
>  >	syncprov-sessionlog <ops>
>  
> @@ -535,7 +554,7 @@
>  >
>  >	overlay syncprov
>  >	syncprov-checkpoint 100 10
> ->	syncprov-sessionlog 100
> +>	syncprov-sessionlog-source cn=accesslog
>  
>  
>  H4: Set up the consumer slapd
> diff -Nru openldap-2.6.9+dfsg/doc/guide/admin/slapdconf2.sdf openldap-2.6.10+dfsg/doc/guide/admin/slapdconf2.sdf
> --- openldap-2.6.9+dfsg/doc/guide/admin/slapdconf2.sdf	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/guide/admin/slapdconf2.sdf	2025-05-22 10:56:21.000000000 -0700
> @@ -1045,102 +1045,103 @@
>  E: 15.    # global database parameters
>  E: 16.    dn: olcDatabase=frontend,cn=config
>  E: 17.    objectClass: olcDatabaseConfig
> -E: 18.    olcDatabase: frontend
> -E: 19.    olcAccess: to * by * read
> -E: 20.
> +E: 18.    objectClass: olcFrontendConfig
> +E: 19.    olcDatabase: frontend
> +E: 20.    olcAccess: to * by * read
> +E: 21.
>  
>  Line 15 is a comment. Lines 16-18 identify this entry as the global
> -database entry. Line 19 is a global access control. It applies to all
> +database entry. Line 20 is a global access control. It applies to all
>  entries (after any applicable database-specific access controls).
> -Line 20 is a blank line.
> +Line 21 is a blank line.
>  
>  The next entry defines the config backend.
>  
> -E: 21.    # set a rootpw for the config database so we can bind.
> -E: 22.    # deny access to everyone else.
> -E: 23.    dn: olcDatabase=config,cn=config
> -E: 24.    objectClass: olcDatabaseConfig
> -E: 25.    olcDatabase: config
> -E: 26.    olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy
> -E: 27.    olcAccess: to * by * none
> -E: 28.
> -
> -Lines 21-22 are comments. Lines 23-25 identify this entry as the config
> -database entry. Line 26 defines the {{super-user}} password for this
> -database. (The DN defaults to {{"cn=config"}}.) Line 27 denies all access
> +E: 22.    # set a rootpw for the config database so we can bind.
> +E: 23.    # deny access to everyone else.
> +E: 24.    dn: olcDatabase=config,cn=config
> +E: 25.    objectClass: olcDatabaseConfig
> +E: 26.    olcDatabase: config
> +E: 27.    olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy
> +E: 28.    olcAccess: to * by * none
> +E: 29.
> +
> +Lines 22-23 are comments. Lines 24-26 identify this entry as the config
> +database entry. Line 27 defines the {{super-user}} password for this
> +database. (The DN defaults to {{"cn=config"}}.) Line 28 denies all access
>  to this database, so only the super-user will be able to access it. (This
>  is already the default access on the config database. It is just listed
>  here for illustration, and to reiterate that unless a means to authenticate
>  as the super-user is explicitly configured, the config database will be
>  inaccessible.)
>  
> -Line 28 is a blank line.
> +Line 29 is a blank line.
>  
>  The next entry defines an MDB backend that will handle queries for things
>  in the "dc=example,dc=com" portion of the tree. Indices are to be maintained
>  for several attributes, and the {{EX:userPassword}} attribute is to be
>  protected from unauthorized access.
>  
> -E: 29.    # MDB definition for example.com
> -E: 30.    dn: olcDatabase=mdb,cn=config
> -E: 31.    objectClass: olcDatabaseConfig
> -E: 32.    objectClass: olcMdbConfig
> -E: 33.    olcDatabase: mdb
> -E: 34.    olcSuffix: dc=example,dc=com
> -E: 35.    olcDbDirectory: /usr/local/var/openldap-data
> -E: 36.    olcRootDN: cn=Manager,dc=example,dc=com
> -E: 37.    olcRootPW: secret
> -E: 38.    olcDbIndex: uid pres,eq
> -E: 39.    olcDbIndex: cn,sn pres,eq,approx,sub
> -E: 40.    olcDbIndex: objectClass eq
> -E: 41.    olcAccess: to attrs=userPassword
> -E: 42.      by self write
> -E: 43.      by anonymous auth
> -E: 44.      by dn.base="cn=Admin,dc=example,dc=com" write
> -E: 45.      by * none
> -E: 46.    olcAccess: to *
> -E: 47.      by self write
> -E: 48.      by dn.base="cn=Admin,dc=example,dc=com" write
> -E: 49.      by * read
> -E: 50.
> -
> -Line 29 is a comment. Lines 30-33 identify this entry as a MDB database
> -configuration entry.  Line 34 specifies the DN suffix
> -for queries to pass to this database. Line 35 specifies the directory
> +E: 30.    # MDB definition for example.com
> +E: 31.    dn: olcDatabase=mdb,cn=config
> +E: 32.    objectClass: olcDatabaseConfig
> +E: 33.    objectClass: olcMdbConfig
> +E: 34.    olcDatabase: mdb
> +E: 35.    olcSuffix: dc=example,dc=com
> +E: 36.    olcDbDirectory: /usr/local/var/openldap-data
> +E: 37.    olcRootDN: cn=Manager,dc=example,dc=com
> +E: 38.    olcRootPW: secret
> +E: 39.    olcDbIndex: uid pres,eq
> +E: 40.    olcDbIndex: cn,sn pres,eq,approx,sub
> +E: 41.    olcDbIndex: objectClass eq
> +E: 42.    olcAccess: to attrs=userPassword
> +E: 43.      by self write
> +E: 44.      by anonymous auth
> +E: 45.      by dn.base="cn=Admin,dc=example,dc=com" write
> +E: 46.      by * none
> +E: 47.    olcAccess: to *
> +E: 48.      by self write
> +E: 49.      by dn.base="cn=Admin,dc=example,dc=com" write
> +E: 50.      by * read
> +E: 51.
> +
> +Line 30 is a comment. Lines 31-34 identify this entry as a MDB database
> +configuration entry.  Line 35 specifies the DN suffix
> +for queries to pass to this database. Line 36 specifies the directory
>  in which the database files will live.
>  
> -Lines 36 and 37 identify the database {{super-user}} entry and associated
> +Lines 37 and 38 identify the database {{super-user}} entry and associated
>  password. This entry is not subject to access control or size or
>  time limit restrictions.
>  
> -Lines 38 through 40 indicate the indices to maintain for various
> +Lines 39 through 41 indicate the indices to maintain for various
>  attributes.
>  
> -Lines 41 through 49 specify access control for entries in this
> +Lines 42 through 50 specify access control for entries in this
>  database. For all applicable entries, the {{EX:userPassword}} attribute is writable
>  by the entry itself and by the "admin" entry.  It may be used for
>  authentication/authorization purposes, but is otherwise not readable.
>  All other attributes are writable by the entry and the "admin"
>  entry, but may be read by all users (authenticated or not).
>  
> -Line 50 is a blank line, indicating the end of this entry.
> +Line 51 is a blank line, indicating the end of this entry.
>  
>  The next entry defines another
>  MDB database. This one handles queries involving the
>  {{EX:dc=example,dc=net}} subtree but is managed by the same entity
> -as the first database.  Note that without line 60, the read access
> -would be allowed due to the global access rule at line 19.
> +as the first database.  Note that without line 61, the read access
> +would be allowed due to the global access rule at line 20.
>  
> -E: 51.    # MDB definition for example.net
> -E: 52.    dn: olcDatabase=mdb,cn=config
> -E: 53.    objectClass: olcDatabaseConfig
> -E: 54.    objectClass: olcMdbConfig
> -E: 55.    olcDatabase: mdb
> -E: 56.    olcSuffix: dc=example,dc=net
> -E: 57.    olcDbDirectory: /usr/local/var/openldap-data-net
> -E: 58.    olcRootDN: cn=Manager,dc=example,dc=com
> -E: 59.    olcDbIndex: objectClass eq
> -E: 60.    olcAccess: to * by users read
> +E: 52.    # MDB definition for example.net
> +E: 53.    dn: olcDatabase=mdb,cn=config
> +E: 54.    objectClass: olcDatabaseConfig
> +E: 55.    objectClass: olcMdbConfig
> +E: 56.    olcDatabase: mdb
> +E: 57.    olcSuffix: dc=example,dc=net
> +E: 58.    olcDbDirectory: /usr/local/var/openldap-data-net
> +E: 59.    olcRootDN: cn=Manager,dc=example,dc=com
> +E: 60.    olcDbIndex: objectClass eq
> +E: 61.    olcAccess: to * by users read
>  
>  
>  H2: Converting old style {{slapd.conf}}(5) file to {{cn=config}} format
> diff -Nru openldap-2.6.9+dfsg/doc/man/man5/ldap.conf.5 openldap-2.6.10+dfsg/doc/man/man5/ldap.conf.5
> --- openldap-2.6.9+dfsg/doc/man/man5/ldap.conf.5	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/man/man5/ldap.conf.5	2025-05-22 10:56:21.000000000 -0700
> @@ -159,7 +159,6 @@
>  of the search.
>  .RE
>  .TP
> -.TP
>  .B HOST <name[:port] ...>
>  Specifies the name(s) of an LDAP server(s) to which the
>  .I LDAP 
> @@ -184,15 +183,18 @@
>  Linux only.
>  .TP
>  .B NETWORK_TIMEOUT <integer>
> -Specifies the timeout (in seconds) after which the poll(2)/select(2)
> -following a connect(2) returns in case of no activity.
> +Specifies the timeout (in seconds) after which the
> +.BR poll (2)/ select (2)
> +following a
> +.BR connect (2)
> +returns in case of no activity.
>  .TP
>  .B PORT <port>
>  Specifies the default port used when connecting to LDAP servers(s).
>  The port may be specified as a number.
>  .B PORT
>  is deprecated in favor of
> -.BR URI.
> +.BR URI .
>  .TP
>  .B REFERRALS <on/true/yes/off/false/no>
>  Specifies if the client should automatically follow referrals returned
> @@ -295,7 +297,7 @@
>  description).  The default is
>  .BR INT_MAX .
>  .TP
> -.B maxbufsize=<factor> 
> +.B maxbufsize=<factor>
>  specifies the maximum security layer receive buffer
>  size allowed.  0 disables security layers.  The default is 65536.
>  .RE
> @@ -338,7 +340,7 @@
>  be specified, separated by a semi-colon.  The
>  .B TLS_CACERT
>  is always used before
> -.B TLS_CACERTDIR.
> +.BR TLS_CACERTDIR .
>  .TP
>  .B TLS_CERT <filename>
>  Specifies the file that contains the client certificate.
> diff -Nru openldap-2.6.9+dfsg/doc/man/man5/slapd-config.5 openldap-2.6.10+dfsg/doc/man/man5/slapd-config.5
> --- openldap-2.6.9+dfsg/doc/man/man5/slapd-config.5	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/man/man5/slapd-config.5	2025-05-22 10:56:21.000000000 -0700
> @@ -572,7 +572,7 @@
>  only go to stderr and are not recorded anywhere else.
>  Specifying a logfile copies messages to both stderr and the logfile.
>  .TP
> -.B olcLogFileFormat: debug | syslog-utc | syslog-localtime
> +.B olcLogFileFormat: debug|syslog-utc|syslog-localtime|rfc3339-utc
>  Specify the prefix format for messages written to the logfile. The debug
>  format is the normal format used for slapd debug messages, with a timestamp
>  in hexadecimal, followed by a thread ID.  The other options are to
> @@ -953,6 +953,13 @@
>  locations will be used. Multiple directories may be specified,
>  separated by a semi-colon.
>  .TP
> +.B olcTLSCACertificate: <CA cert>
> +Stores a single CA certificate that will be trusted by the server, in DER format.
> +If this option is set, the \fBolcTLSCACertificateFile\fP and
> +\fBolcTLSCACertificatePath\fP options are ignored. If multiple
> +CA certificates are required, the \fBolcTLSCACertificateFile\fP
> +or \fBolcTLSCACertificatePath\fP options must be used instead of this option.
> +.TP
>  .B olcTLSCertificateFile: <filename>
>  Specifies the file that contains the
>  .B slapd
> @@ -961,17 +968,24 @@
>  When using OpenSSL that file may also contain any number of intermediate
>  certificates after the server certificate.
>  .TP
> +.B olcTLSCertificate: <cert>
> +Stores a single certificate for the server, in DER format. If this option is
> +used, the \fBolcTLSCertificateFile\fP option is ignored.
> +.TP
>  .B olcTLSCertificateKeyFile: <filename>
>  Specifies the file that contains the
>  .B slapd
> -server private key that matches the certificate stored in the
> -.B olcTLSCertificateFile
> -file. If the private key is protected with a password, the password must
> +server private key that matches the specified server certificate.
> +If the private key file is protected with a password, the password must
>  be manually typed in when slapd starts.  Usually the private key is not
>  protected with a password, to allow slapd to start without manual
>  intervention, so
>  it is of critical importance that the file is protected carefully. 
>  .TP
> +.B olcTLSCertificateKey <key>
> +Stores the private key that matches the server certificate. If this option is
> +used, the \fBolcTLSCertificateKeyFile\fP option is ignored.
> +.TP
>  .B olcTLSDHParamFile: <filename>
>  This directive specifies the file that contains parameters for Diffie-Hellman
>  ephemeral key exchange.  This is required in order to use a DSA certificate on
> diff -Nru openldap-2.6.9+dfsg/doc/man/man5/slapd.conf.5 openldap-2.6.10+dfsg/doc/man/man5/slapd.conf.5
> --- openldap-2.6.9+dfsg/doc/man/man5/slapd.conf.5	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/man/man5/slapd.conf.5	2025-05-22 10:56:21.000000000 -0700
> @@ -626,7 +626,7 @@
>  only go to stderr and are not recorded anywhere else.
>  Specifying a logfile copies messages to both stderr and the logfile.
>  .TP
> -.B logfile-format debug | syslog-utc | syslog-localtime
> +.B logfile-format debug|syslog-utc|syslog-localtime|rfc3339-utc
>  Specify the prefix format for messages written to the logfile. The debug
>  format is the normal format used for slapd debug messages, with a timestamp
>  in hexadecimal, followed by a thread ID.  The other options are to
> diff -Nru openldap-2.6.9+dfsg/doc/man/man5/slapo-dynlist.5 openldap-2.6.10+dfsg/doc/man/man5/slapo-dynlist.5
> --- openldap-2.6.9+dfsg/doc/man/man5/slapo-dynlist.5	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/man/man5/slapo-dynlist.5	2025-05-22 10:56:21.000000000 -0700
> @@ -128,6 +128,9 @@
>  .B static-oc
>  objectClass is also specified, then the memberOf attribute will also be
>  populated with the DNs of the static groups that an entry is a member of.
> +Note that using the same
> +.B static-oc
> +objectClass in more than one dynamic group configuration is not supported.
>  If the optional
>  .B *
>  character is also specified, then the member and memberOf values will be
> diff -Nru openldap-2.6.9+dfsg/doc/man/man8/slapacl.8 openldap-2.6.10+dfsg/doc/man/man8/slapacl.8
> --- openldap-2.6.9+dfsg/doc/man/man8/slapacl.8	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/doc/man/man8/slapacl.8	2025-05-22 10:56:21.000000000 -0700
> @@ -131,15 +131,15 @@
>  for details.
>  .RE
>  .TP
> -.BI \-u
> -do not fetch the entry from the database.
> -In this case, if the entry does not exist, a fake entry with the
> +.B \-u
> +enable dry-run mode. Do not fetch any entries from the database.
> +In this case, a fake entry with the
>  .I DN
>  given with the
>  .B \-b
>  option is used, with no attributes.
>  As a consequence, those rules that depend on the contents 
> -of the target object will not behave as with the real object.
> +of the target object or any other database objects will not behave as with the real object.
>  The
>  .I DN
>  given with the
> diff -Nru openldap-2.6.9+dfsg/libraries/libldap/error.c openldap-2.6.10+dfsg/libraries/libldap/error.c
> --- openldap-2.6.9+dfsg/libraries/libldap/error.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/libraries/libldap/error.c	2025-05-22 10:56:21.000000000 -0700
> @@ -261,6 +261,25 @@
>  	LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
>  	/* Find the result, last msg in chain... */
>  	lm = r->lm_chain_tail;
> +	if ( r->lm_msgid != lm->lm_msgid ) {
> +		/*
> +		 * ITS#10229: Returned with LDAP_MSG_ALL+LDAP_MSG_RECEIVED. People who
> +		 * do that aren't expected to call ldap_parse_result not least because
> +		 * they have no idea what the msgid of the result would be. Just do our
> +		 * best.
> +		 *
> +		 * We could also return LDAP_NO_RESULTS_RETURNED if there isn't a
> +		 * result for r's operation.
> +		 */
> +		lm = r;
> +		for ( lm = r; lm; lm = lm->lm_chain ) {
> +			if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
> +					lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE &&
> +					lm->lm_msgtype != LDAP_RES_INTERMEDIATE )
> +				break;
> +		}
> +	}
> +
>  	/* FIXME: either this is not possible (assert?)
>  	 * or it should be handled */
>  	if ( lm != NULL ) {
> diff -Nru openldap-2.6.9+dfsg/libraries/libldap/result.c openldap-2.6.10+dfsg/libraries/libldap/result.c
> --- openldap-2.6.9+dfsg/libraries/libldap/result.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/libraries/libldap/result.c	2025-05-22 10:56:21.000000000 -0700
> @@ -146,8 +146,32 @@
>  		"ldap_chkResponseList ld %p msgid %d all %d\n",
>  		(void *)ld, msgid, all );
>  
> +	lm = ld->ld_responses;
> +	if ( lm && msgid == LDAP_RES_ANY && all == LDAP_MSG_RECEIVED ) {
> +		/*
> +		 * ITS#10229: asked to return all messages received so far,
> +		 * draft-ietf-ldapext-ldap-c-api which defines LDAP_MSG_RECEIVED lets
> +		 * us mix different msgids in what we return
> +		 *
> +		 * We have two choices in *how* we return the messages:
> +		 * - we link all chains together
> +		 * - we keep the chains intact and use lm_next
> +		 *
> +		 * The former will make life harder for ldap_parse_result finding a
> +		 * result message, the latter affects routines that iterate over
> +		 * messages. This take does the former.
> +		 */
> +		ld->ld_responses = NULL;
> +		while ( lm->lm_next ) {
> +			lm->lm_chain_tail->lm_chain = lm->lm_next;
> +			lm->lm_chain_tail = lm->lm_next->lm_chain_tail;
> +			lm->lm_next = lm->lm_next->lm_next;
> +		}
> +		return lm;
> +	}
> +
>  	lastlm = &ld->ld_responses;
> -	for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
> +	for ( ; lm != NULL; lm = nextlm ) {
>  		nextlm = lm->lm_next;
>  		++cnt;
>  
> @@ -387,6 +411,37 @@
>  			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
>  		}
>  
> +		if ( all == LDAP_MSG_RECEIVED ) {
> +			/*
> +			 * ITS#10229: we looped over all ready connections accumulating
> +			 * messages in ld_responses, check if we have something to return
> +			 * right now.
> +			 */
> +			LDAPMessage **lp, *lm = ld->ld_responses;
> +
> +			if ( lm && msgid == LDAP_RES_ANY ) {
> +				*result = lm;
> +
> +				ld->ld_responses = NULL;
> +				while ( lm->lm_next ) {
> +					lm->lm_chain_tail->lm_chain = lm->lm_next;
> +					lm->lm_chain_tail = lm->lm_next->lm_chain_tail;
> +					lm->lm_next = lm->lm_next->lm_next;
> +				}
> +				rc = lm->lm_msgtype;
> +				break;
> +			}
> +
> +			for ( lp = &ld->ld_responses; lm; lp = &lm->lm_next, lm = *lp ) {
> +				if ( msgid == lm->lm_msgid ) break;
> +			}
> +			if ( lm ) {
> +				*lp = lm->lm_next;
> +				*result = lm;
> +				rc = lm->lm_msgtype;
> +			}
> +		}
> +
>  		if ( rc == LDAP_MSG_X_KEEP_LOOKING && tvp != NULL ) {
>  			struct timeval	curr_time_tv = { 0 },
>  					delta_time_tv = { 0 };
> @@ -1096,7 +1151,10 @@
>  
>  	/* is this the one we're looking for? */
>  	if ( msgid == LDAP_RES_ANY || id == msgid ) {
> -		if ( all == LDAP_MSG_ONE
> +		if ( msgid == LDAP_RES_ANY && all == LDAP_MSG_RECEIVED ) {
> +			/* ITS#10229: We want to keep going so long as there's anything to
> +			 * read. */
> +		} else if ( all == LDAP_MSG_ONE
>  			|| ( newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT
>  				&& newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY
>  				&& newmsg->lm_msgtype != LDAP_RES_INTERMEDIATE
> diff -Nru openldap-2.6.9+dfsg/libraries/librewrite/subst.c openldap-2.6.10+dfsg/libraries/librewrite/subst.c
> --- openldap-2.6.9+dfsg/libraries/librewrite/subst.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/libraries/librewrite/subst.c	2025-05-22 10:56:21.000000000 -0700
> @@ -131,6 +131,7 @@
>  				map = rewrite_xmap_parse( info,
>  						p + 3, (const char **)&begin );
>  				if ( map == NULL ) {
> +					nsub++;	/* make sure subs[nsub] is freed */
>  					goto cleanup;
>  				}
>  				submatch[ nsub ].ls_map = map;
> @@ -146,6 +147,7 @@
>  			map = rewrite_map_parse( info, p + 2,
>  					(const char **)&begin );
>  			if ( map == NULL ) {
> +				nsub++;	/* make sure subs[nsub] is freed */
>  				goto cleanup;
>  			}
>  			p = begin - 1;
> @@ -165,6 +167,7 @@
>  			continue;
>  
>  		} else {
> +			nsub++;	/* make sure subs[nsub] is freed */
>  			goto cleanup;
>  		}
>  
> @@ -176,10 +179,6 @@
>  	 */
>  	tmps = (struct berval * )realloc( subs, sizeof( struct berval )*( nsub + 1 ) );
>  	if ( tmps == NULL ) {
> -		/*
> -		 * XXX need to free the value subst stuff!
> -		 */
> -		free( subs );
>  		goto cleanup;
>  	}
>  	subs = tmps;
> @@ -200,6 +199,7 @@
>  
>  	s = calloc( sizeof( struct rewrite_subst ), 1 );
>  	if ( s == NULL ) {
> +		nsub++;	/* make sure last elements are freed */
>  		goto cleanup;
>  	}
>  
> @@ -213,13 +213,13 @@
>  cleanup:;
>  	if ( subs ) {
>  		for ( l=0; l<nsub; l++ ) {
> -			free( subs[nsub].bv_val );
> +			free( subs[l].bv_val );
>  		}
>  		free( subs );
>  	}
>  	if ( submatch ) {
>  		for ( l=0; l<nsub; l++ ) {
> -			free( submatch[nsub].ls_map );
> +			free( submatch[l].ls_map );
>  		}
>  		free( submatch );
>  	}
> diff -Nru openldap-2.6.9+dfsg/servers/lloadd/config.c openldap-2.6.10+dfsg/servers/lloadd/config.c
> --- openldap-2.6.9+dfsg/servers/lloadd/config.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/lloadd/config.c	2025-05-22 10:56:21.000000000 -0700
> @@ -3767,6 +3767,10 @@
>              }
>  #endif /* ! HAVE_TLS */
>              b->b_tls_conf = tlskey[i].mask;
> +            if ( b->b_tls != LLOAD_LDAPS ) {
> +                b->b_tls = b->b_tls_conf;
> +                flag = LLOAD_BACKEND_MOD_OTHER;
> +            }
>          } break;
>          case CFG_WEIGHT:
>              b->b_weight = c->value_uint;
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/back-ldif/ldif.c openldap-2.6.10+dfsg/servers/slapd/back-ldif/ldif.c
> --- openldap-2.6.9+dfsg/servers/slapd/back-ldif/ldif.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/back-ldif/ldif.c	2025-05-22 10:56:21.000000000 -0700
> @@ -1576,28 +1576,6 @@
>  		goto done;
>  	}
>  
> -	rc = ndn2path( op, &op->o_req_ndn, &path, 0 );
> -	if ( rc != LDAP_SUCCESS ) {
> -		goto done;
> -	}
> -
> -	ldif2dir_len( path );
> -	ldif2dir_name( path );
> -	if ( rmdir( path.bv_val ) < 0 ) {
> -		switch ( errno ) {
> -		case ENOTEMPTY:
> -			rc = LDAP_NOT_ALLOWED_ON_NONLEAF;
> -			break;
> -		case ENOENT:
> -			/* is leaf, go on */
> -			break;
> -		default:
> -			rc = LDAP_OTHER;
> -			rs->sr_text = "internal error (cannot delete subtree directory)";
> -			break;
> -		}
> -	}
> -
>  	/* pre-read */
>  	if ( op->o_preread ) {
>  		Entry *e = NULL;
> @@ -1620,6 +1598,29 @@
>  			}
>  		}
>  		entry_free( e );
> +	} else {
> +		rc = ndn2path( op, &op->o_req_ndn, &path, 0 );
> +	}
> +
> +	if ( rc != LDAP_SUCCESS ) {
> +		goto done;
> +	}
> +
> +	ldif2dir_len( path );
> +	ldif2dir_name( path );
> +	if ( rmdir( path.bv_val ) < 0 ) {
> +		switch ( errno ) {
> +		case ENOTEMPTY:
> +			rc = LDAP_NOT_ALLOWED_ON_NONLEAF;
> +			break;
> +		case ENOENT:
> +			/* is leaf, go on */
> +			break;
> +		default:
> +			rc = LDAP_OTHER;
> +			rs->sr_text = "internal error (cannot delete subtree directory)";
> +			break;
> +		}
>  	}
>  
>  	if ( rc == LDAP_SUCCESS ) {
> @@ -1742,12 +1743,39 @@
>  	char textbuf[SLAP_TEXT_BUFLEN];
>  	int rc, same_ndn;
>  
> +	LDAPControl **preread_ctrl = NULL;
> +	LDAPControl **postread_ctrl = NULL;
> +	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
> +	int num_ctrls = 0;
> +
> +	ctrls[num_ctrls] = NULL;
> +
>  	slap_mods_opattrs( op, &op->orr_modlist, 1 );
>  
>  	ldap_pvt_thread_mutex_lock( &li->li_modop_mutex );
>  
>  	rc = get_entry( op, &entry, &old_path, &rs->sr_text );
>  	if ( rc == LDAP_SUCCESS ) {
> +		if ( op->o_preread ) {
> +			if ( preread_ctrl == NULL ) {
> +				preread_ctrl = &ctrls[num_ctrls++];
> +				ctrls[num_ctrls] = NULL;
> +			}
> +			if ( slap_read_controls( op, rs, entry,
> +				&slap_pre_read_bv, preread_ctrl ) )
> +			{
> +				Debug( LDAP_DEBUG_ANY, "ldif_back_modify: "
> +					"pre-read failed \"%s\"\n",
> +					entry->e_name.bv_val );
> +				if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
> +					/* FIXME: is it correct to abort
> +					 * operation if control fails? */
> +					rc = rs->sr_err;
> +					goto done;
> +				}
> +			}
> +		}
> +
>  		same_ndn = !ber_bvcmp( &entry->e_nname, &op->orr_nnewDN );
>  		ber_bvreplace( &entry->e_name, &op->orr_newDN );
>  		ber_bvreplace( &entry->e_nname, &op->orr_nnewDN );
> @@ -1758,11 +1786,32 @@
>  			rc = ldif_move_entry( op, entry, same_ndn, &old_path,
>  				&rs->sr_text );
>  
> +		if ( rc == LDAP_SUCCESS && op->o_postread ) {
> +			if ( postread_ctrl == NULL ) {
> +				postread_ctrl = &ctrls[num_ctrls++];
> +				ctrls[num_ctrls] = NULL;
> +			}
> +			if ( slap_read_controls( op, rs, entry,
> +				&slap_post_read_bv, postread_ctrl ) )
> +			{
> +				Debug( LDAP_DEBUG_ANY, "ldif_back_modify: "
> +					"post-read failed \"%s\"\n",
> +					entry->e_name.bv_val );
> +				if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
> +					/* FIXME: is it correct to abort
> +					 * operation if control fails? */
> +					rc = rs->sr_err;
> +				}
> +			}
> +		}
> +
>  		entry_free( entry );
>  		SLAP_FREE( old_path.bv_val );
>  	}
>  
> +done:
>  	ldap_pvt_thread_mutex_unlock( &li->li_modop_mutex );
> +	if ( num_ctrls ) rs->sr_ctrls = ctrls;
>  	rs->sr_err = rc;
>  	send_ldap_result( op, rs );
>  	slap_graduate_commit_csn( op );
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/back-mdb/attr.c openldap-2.6.10+dfsg/servers/slapd/back-mdb/attr.c
> --- openldap-2.6.9+dfsg/servers/slapd/back-mdb/attr.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/back-mdb/attr.c	2025-05-22 10:56:21.000000000 -0700
> @@ -98,6 +98,9 @@
>  	int i, flags;
>  	int rc;
>  
> +	if ( !mdb->mi_nattrs )
> +		return 0;
> +
>  	txn = tx0;
>  	if ( txn == NULL ) {
>  		rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &txn );
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/back-mdb/config.c openldap-2.6.10+dfsg/servers/slapd/back-mdb/config.c
> --- openldap-2.6.9+dfsg/servers/slapd/back-mdb/config.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/back-mdb/config.c	2025-05-22 10:56:21.000000000 -0700
> @@ -371,6 +371,9 @@
>  	int i, rc, changed = 0;
>  	unsigned short s;
>  
> +	if ( !mdb->mi_nattrs )
> +		return 0;
> +
>  	rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &txn );
>  	if ( rc )
>  		return rc;
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/back-mdb/delete.c openldap-2.6.10+dfsg/servers/slapd/back-mdb/delete.c
> --- openldap-2.6.9+dfsg/servers/slapd/back-mdb/delete.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/back-mdb/delete.c	2025-05-22 10:56:21.000000000 -0700
> @@ -148,17 +148,18 @@
>  			"<=- " LDAP_XSTRING(mdb_delete) ": no such object %s\n",
>  			op->o_req_dn.bv_val );
>  
> -		rs->sr_matched = ch_strdup( e->e_dn );
> -		if ( is_entry_referral( e )) {
> -			BerVarray ref = get_entry_referrals( op, e );
> -			rs->sr_ref = referral_rewrite( ref, &e->e_name,
> -				&op->o_req_dn, LDAP_SCOPE_DEFAULT );
> -			ber_bvarray_free( ref );
> -		} else {
> -			rs->sr_ref = NULL;
> +		rs->sr_ref = NULL;
> +		if ( e ) {
> +			rs->sr_matched = ch_strdup( e->e_dn );
> +			if ( is_entry_referral( e )) {
> +				BerVarray ref = get_entry_referrals( op, e );
> +				rs->sr_ref = referral_rewrite( ref, &e->e_name,
> +					&op->o_req_dn, LDAP_SCOPE_DEFAULT );
> +				ber_bvarray_free( ref );
> +			}
> +			mdb_entry_return( op, e );
> +			e = NULL;
>  		}
> -		mdb_entry_return( op, e );
> -		e = NULL;
>  
>  		rs->sr_err = LDAP_REFERRAL;
>  		rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/back-mdb/tools.c openldap-2.6.10+dfsg/servers/slapd/back-mdb/tools.c
> --- openldap-2.6.9+dfsg/servers/slapd/back-mdb/tools.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/back-mdb/tools.c	2025-05-22 10:56:21.000000000 -0700
> @@ -1051,7 +1051,7 @@
>  	op.o_tmpmfuncs = &ch_mfuncs;
>  
>  	/* id2entry index */
> -	rc = mdb_id2entry_update( &op, mdb_tool_txn, NULL, e );
> +	rc = mdb_id2entry_update( &op, mdb_tool_txn, idcursor, e );
>  	if( rc != 0 ) {
>  		snprintf( text->bv_val, text->bv_len,
>  				"id2entry_update failed: err=%d", rc );
> @@ -1086,6 +1086,7 @@
>  		e->e_id = NOID;
>  	}
>  	mdb_tool_txn = NULL;
> +	idcursor = NULL;
>  
>  	return e->e_id;
>  }
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/bconfig.c openldap-2.6.10+dfsg/servers/slapd/bconfig.c
> --- openldap-2.6.9+dfsg/servers/slapd/bconfig.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/bconfig.c	2025-05-22 10:56:21.000000000 -0700
> @@ -1112,6 +1112,26 @@
>  	return LDAP_SUCCESS;
>  }
>  
> +static int
> +config_copy_controls( Operation *op, SlapReply *rs )
> +{
> +	/* Accumulate response controls so we can return them to client */
> +	if ( rs->sr_ctrls ) {
> +		LDAPControl **prepared = op->o_callback->sc_private,
> +					**received = rs->sr_ctrls;
> +		slap_mask_t oldflags = rs->sr_flags;
> +
> +		rs->sr_ctrls = prepared;
> +		rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
> +		slap_add_ctrls( op, rs, received );
> +		op->o_callback->sc_private = rs->sr_ctrls;
> +
> +		rs->sr_ctrls = received;
> +		rs->sr_flags = oldflags;
> +	}
> +	return 0;
> +}
> +
>  #define	GOT_CONFIG	1
>  #define	GOT_FRONTEND	2
>  static int
> @@ -2952,13 +2972,16 @@
>  		}
>  
>  		if ( c->argc == 2 ) {
> -			if ( strcasecmp( c->argv[1], "advertise" ) == 0 ) {
> +			if ( strcasecmp( c->argv[1], "FALSE" ) == 0 ) {
> +				rc = 0;
> +				break;
> +			} else if ( strcasecmp( c->argv[1], "advertise" ) == 0 ) {
>  				advertise = 1;
>  
>  			} else if ( strcasecmp( c->argv[1], "TRUE" ) != 0 ) {
>  				/* log error */
>  				snprintf( c->cr_msg, sizeof( c->cr_msg),
> -					"subordinate must be \"TRUE\" or \"advertise\"" );
> +					"subordinate must be \"TRUE\", \"FALSE\" or \"advertise\"" );
>  				Debug( LDAP_DEBUG_ANY,
>  					"%s: suffix \"%s\": %s.\n",
>  					c->log, c->be->be_suffix[0].bv_val, c->cr_msg );
> @@ -4821,7 +4844,7 @@
>  	if ( use_ldif ) {
>  		CfBackInfo *cfb = (CfBackInfo *)op->o_bd->be_private;
>  		BackendDB *be = op->o_bd;
> -		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
> +		slap_callback sc = { NULL, config_copy_controls, NULL, rs->sr_ctrls }, *scp;
>  		struct berval dn, ndn, xdn, xndn;
>  
>  		op->o_bd = &cfb->cb_db;
> @@ -4838,6 +4861,8 @@
>  
>  		scp = op->o_callback;
>  		op->o_callback = &sc;
> +		rs->sr_ctrls = NULL;
> +
>  		op->orr_newrdn = *newrdn;
>  		op->orr_nnewrdn = *nnewrdn;
>  		op->orr_newSup = NULL;
> @@ -4857,6 +4882,9 @@
>  		op->o_ndn = ndn;
>  		op->o_req_dn = xdn;
>  		op->o_req_ndn = xndn;
> +
> +		rs->sr_ctrls = sc.sc_private;
> +		rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
>  	}
>  	free( odn.bv_val );
>  	free( ondn.bv_val );
> @@ -5648,6 +5676,7 @@
>  	CfEntryInfo *ce2, *ce3, *cetmp = NULL, *cerem = NULL;
>  	ConfigType etype = ce->ce_type;
>  	int count = 0, rc = 0;
> +	char preread = op->o_preread, postread = op->o_postread;
>  
>  	/* Reverse ce list */
>  	for (ce2 = ce->ce_sibs;ce2;ce2 = ce3) {
> @@ -5665,6 +5694,9 @@
>  		}
>  	}
>  
> +	/* Suppress control generation for internal ops */
> +	op->o_postread = SLAP_CONTROL_NONE;
> +
>  	/* Move original to a temp name until increments are done */
>  	if ( rebase ) {
>  		ce->ce_entry->e_private = NULL;
> @@ -5672,6 +5704,8 @@
>  			base+BIGTMP, 0, use_ldif );
>  		ce->ce_entry->e_private = ce;
>  	}
> +	op->o_preread = SLAP_CONTROL_NONE;
> +
>  	/* start incrementing */
>  	for (ce2=cetmp; ce2; ce2=ce3) {
>  		ce3 = ce2->ce_sibs;
> @@ -5682,9 +5716,12 @@
>  				count+base, 0, use_ldif );
>  		count--;
>  	}
> +
> +	op->o_postread = postread;
>  	if ( rebase )
>  		rc = config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
>  			base, 0, use_ldif );
> +	op->o_preread = preread;
>  	return rc;
>  }
>  
> @@ -5692,7 +5729,11 @@
>  config_rename_del( Operation *op, SlapReply *rs, CfEntryInfo *ce,
>  	CfEntryInfo *ce2, int old, int use_ldif )
>  {
> -	int count = 0;
> +	int rc, count = 0;
> +	char preread = op->o_preread, postread = op->o_postread;
> +
> +	/* Suppress control generation for internal ops */
> +	op->o_postread = SLAP_CONTROL_NONE;
>  
>  	/* Renumber original to a temp value */
>  	ce->ce_entry->e_private = NULL;
> @@ -5700,14 +5741,20 @@
>  		old+BIGTMP, 0, use_ldif );
>  	ce->ce_entry->e_private = ce;
>  
> +	op->o_preread = SLAP_CONTROL_NONE;
> +
>  	/* start decrementing */
>  	for (; ce2 != ce; ce2=ce2->ce_sibs) {
>  		config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry,
>  			count+old, 0, use_ldif );
>  		count++;
>  	}
> -	return config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
> +
> +	op->o_postread = postread;
> +	rc = config_renumber_one( op, rs, ce->ce_parent, ce->ce_entry,
>  		count+old, 0, use_ldif );
> +	op->o_preread = preread;
> +	return rc;
>  }
>  
>  /* Parse an LDAP entry into config directives, then store in underlying
> @@ -5723,7 +5770,9 @@
>  	LDAPControl **postread_ctrl = NULL;
>  	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
>  	int num_ctrls = 0;
> +	char postread = op->o_postread;
>  
> +	op->o_postread = SLAP_CONTROL_NONE;
>  	ctrls[num_ctrls] = NULL;
>  
>  	if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
> @@ -5805,7 +5854,7 @@
>  
>  	if ( cfb->cb_use_ldif ) {
>  		BackendDB *be = op->o_bd;
> -		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
> +		slap_callback sc = { NULL, config_copy_controls, NULL, rs->sr_ctrls }, *scp;
>  		struct berval dn, ndn;
>  
>  		op->o_bd = &cfb->cb_db;
> @@ -5818,12 +5867,18 @@
>  
>  		scp = op->o_callback;
>  		op->o_callback = &sc;
> +		op->o_postread = postread;
> +		rs->sr_ctrls = NULL;
> +
>  		op->o_bd->be_add( op, rs );
>  		op->o_bd = be;
>  		op->o_callback = scp;
>  		op->o_dn = dn;
>  		op->o_ndn = ndn;
> -	} else if ( op->o_postread ) {
> +
> +		rs->sr_ctrls = sc.sc_private;
> +		rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
> +	} else if ( postread ) {
>  		if ( postread_ctrl == NULL ) {
>  			postread_ctrl = &ctrls[num_ctrls++];
>  			ctrls[num_ctrls] = NULL;
> @@ -6277,7 +6332,7 @@
>  config_back_modify( Operation *op, SlapReply *rs )
>  {
>  	CfBackInfo *cfb;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  	Modifications *ml;
>  	ConfigArgs ca = {0};
>  	struct berval rdn;
> @@ -6389,7 +6444,7 @@
>  		rs->sr_text = ca.cr_msg;
>  	} else if ( cfb->cb_use_ldif ) {
>  		BackendDB *be = op->o_bd;
> -		slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
> +		slap_callback sc = { NULL, config_copy_controls, NULL, rs->sr_ctrls }, *scp;
>  		struct berval dn, ndn;
>  
>  		op->o_bd = &cfb->cb_db;
> @@ -6401,11 +6456,16 @@
>  
>  		scp = op->o_callback;
>  		op->o_callback = &sc;
> +		rs->sr_ctrls = NULL;
> +
>  		op->o_bd->be_modify( op, rs );
>  		op->o_bd = be;
>  		op->o_callback = scp;
>  		op->o_dn = dn;
>  		op->o_ndn = ndn;
> +
> +		rs->sr_ctrls = sc.sc_private;
> +		rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
>  	} else if ( op->o_postread ) {
>  		if ( postread_ctrl == NULL ) {
>  			postread_ctrl = &ctrls[num_ctrls++];
> @@ -6435,7 +6495,7 @@
>  config_back_modrdn( Operation *op, SlapReply *rs )
>  {
>  	CfBackInfo *cfb;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  	struct berval rdn;
>  	int ixold, ixnew, dopause = 1;
>  
> @@ -6443,8 +6503,10 @@
>  	LDAPControl **postread_ctrl = NULL;
>  	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
>  	int num_ctrls = 0;
> +	char preread = op->o_preread, postread = op->o_postread;
>  
>  	ctrls[num_ctrls] = NULL;
> +	op->o_preread = op->o_postread = SLAP_CONTROL_NONE;
>  
>  	cfb = (CfBackInfo *)op->o_bd->be_private;
>  
> @@ -6563,7 +6625,7 @@
>  	}
>  
>  	/* If we have a backend, it will handle the control */
> -	if ( !cfb->cb_use_ldif && op->o_preread ) {
> +	if ( !cfb->cb_use_ldif && preread > SLAP_CONTROL_IGNORED ) {
>  		if ( preread_ctrl == NULL ) {
>  			preread_ctrl = &ctrls[num_ctrls++];
>  			ctrls[num_ctrls] = NULL;
> @@ -6606,6 +6668,8 @@
>  		Attribute *a;
>  		rs->sr_err = config_rename_attr( rs, ce->ce_entry, &rdn, &a );
>  		if ( rs->sr_err == LDAP_SUCCESS ) {
> +			op->o_preread = preread;
> +			op->o_postread = postread;
>  			rs->sr_err = config_rename_one( op, rs, ce->ce_entry,
>  				ce->ce_parent, a, &op->orr_newrdn, &op->orr_nnewrdn,
>  				cfb->cb_use_ldif );
> @@ -6653,7 +6717,9 @@
>  			backend_db_move( ce->ce_be, ixnew );
>  		else if ( ce->ce_type == Cft_Overlay )
>  			overlay_move( ce->ce_be, (slap_overinst *)ce->ce_bi, ixnew );
> -			
> +
> +		op->o_preread = preread;
> +		op->o_postread = postread;
>  		if ( ixold < ixnew ) {
>  			rs->sr_err = config_rename_del( op, rs, ce, ceold, ixold,
>  				cfb->cb_use_ldif );
> @@ -6664,7 +6730,8 @@
>  		op->oq_modrdn = modr;
>  	}
>  
> -	if ( rs->sr_err == LDAP_SUCCESS && !cfb->cb_use_ldif && op->o_postread ) {
> +	if ( rs->sr_err == LDAP_SUCCESS && !cfb->cb_use_ldif &&
> +			postread > SLAP_CONTROL_IGNORED ) {
>  		if ( postread_ctrl == NULL ) {
>  			postread_ctrl = &ctrls[num_ctrls++];
>  			ctrls[num_ctrls] = NULL;
> @@ -6694,20 +6761,23 @@
>  {
>  #ifdef SLAP_CONFIG_DELETE
>  	CfBackInfo *cfb;
> -	CfEntryInfo *ce, *last, *ce2;
> +	CfEntryInfo *ce, *ce2, *last = NULL;
>  	int dopause = 1;
>  
>  	LDAPControl **preread_ctrl = NULL;
>  	LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
>  	int num_ctrls = 0;
>  
> +	char preread = op->o_preread;
> +
>  	ctrls[num_ctrls] = NULL;
> +	op->o_preread = SLAP_CONTROL_NONE;
>  
>  	cfb = (CfBackInfo *)op->o_bd->be_private;
>  
>  	/* If we have a backend, it will handle the control */
>  	ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
> -	if ( ce && !cfb->cb_use_ldif && op->o_preread ) {
> +	if ( ce && !cfb->cb_use_ldif && preread ) {
>  		if ( preread_ctrl == NULL ) {
>  			preread_ctrl = &ctrls[num_ctrls++];
>  			ctrls[num_ctrls] = NULL;
> @@ -6718,7 +6788,7 @@
>  			Debug( LDAP_DEBUG_ANY, "config_back_delete: "
>  					"pre-read failed \"%s\"\n",
>  					ce->ce_entry->e_name.bv_val );
> -			if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
> +			if ( preread & SLAP_CONTROL_CRITICAL ) {
>  				/* FIXME: is it correct to abort
>  				 * operation if control fails? */
>  				goto out;
> @@ -6816,7 +6886,7 @@
>  		/* remove from underlying database */
>  		if ( cfb->cb_use_ldif ) {
>  			BackendDB *be = op->o_bd;
> -			slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
> +			slap_callback sc = { NULL, config_copy_controls, NULL, rs->sr_ctrls }, *scp;
>  			struct berval dn, ndn, req_dn, req_ndn;
>  
>  			op->o_bd = &cfb->cb_db;
> @@ -6833,6 +6903,9 @@
>  
>  			scp = op->o_callback;
>  			op->o_callback = &sc;
> +			op->o_preread = preread;
> +			rs->sr_ctrls = NULL;
> +
>  			op->o_bd->be_delete( op, rs );
>  			op->o_bd = be;
>  			op->o_callback = scp;
> @@ -6840,7 +6913,11 @@
>  			op->o_ndn = ndn;
>  			op->o_req_dn = req_dn;
>  			op->o_req_ndn = req_ndn;
> +
> +			rs->sr_ctrls = sc.sc_private;
> +			rs->sr_flags |= REP_CTRLS_MUSTBEFREED;
>  		}
> +		op->o_preread = SLAP_CONTROL_NONE;
>  
>  		/* renumber siblings */
>  		iptr = ber_bvchr( &op->o_req_ndn, '{' ) + 1;
> @@ -6873,12 +6950,19 @@
>  config_back_search( Operation *op, SlapReply *rs )
>  {
>  	CfBackInfo *cfb;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  	slap_mask_t mask;
> +	int paused = 0;
>  
>  	cfb = (CfBackInfo *)op->o_bd->be_private;
>  
> -	ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );
> +	if ( ldap_pvt_thread_pool_query( &connection_pool,
> +			LDAP_PVT_THREAD_POOL_PARAM_PAUSED, &paused ) ) {
> +		return -1;
> +	}
> +	if ( !paused ) {
> +		ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );
> +	}
>  	ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
>  	if ( !ce ) {
>  		if ( last )
> @@ -6913,7 +6997,8 @@
>  	}
>  
>  out:
> -	ldap_pvt_thread_rdwr_runlock( &cfb->cb_rwlock );
> +	if ( !paused )
> +		ldap_pvt_thread_rdwr_runlock( &cfb->cb_rwlock );
>  	send_ldap_result( op, rs );
>  	return rs->sr_err;
>  }
> @@ -6954,7 +7039,7 @@
>  	Entry **ent )
>  {
>  	CfBackInfo *cfb;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  	Entry *e = NULL;
>  	int paused = 0, rc = LDAP_NO_SUCH_OBJECT;
>  
> @@ -7266,7 +7351,7 @@
>  {
>  	struct berval schema_dn = BER_BVC(SCHEMA_RDN "," CONFIG_RDN);
>  	ConfigArgs c = {0};
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  	Entry *e;
>  
>  	/* If there's no root entry, we must be in the midst of converting */
> @@ -7974,7 +8059,7 @@
>  {
>  	CfBackInfo *cfb = be->be_private;
>  	BackendInfo *bi = cfb->cb_db.bd_info;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  
>  	ce = config_find_base( cfb->cb_root, &e->e_nname, &last, NULL );
>  
> @@ -7989,7 +8074,7 @@
>  {
>  	CfBackInfo *cfb = be->be_private;
>  	BackendInfo *bi = cfb->cb_db.bd_info;
> -	CfEntryInfo *ce, *last;
> +	CfEntryInfo *ce, *last = NULL;
>  
>  	ce = config_find_base( cfb->cb_root, ndn, &last, NULL );
>  
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/logging.c openldap-2.6.10+dfsg/servers/slapd/logging.c
> --- openldap-2.6.9+dfsg/servers/slapd/logging.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/logging.c	2025-05-22 10:56:21.000000000 -0700
> @@ -46,14 +46,21 @@
>  static int splen;
>  static int logfile_rotfail, logfile_openfail;
>  
> -typedef enum { LFMT_DEFAULT, LFMT_DEBUG, LFMT_SYSLOG_UTC, LFMT_SYSLOG_LOCAL } LogFormat;
> +typedef enum { LFMT_DEBUG, LFMT_SYSLOG, LFMT_RFC3339 } LogFormat;
>  static LogFormat logfile_format;
>  
> +#define LFMT_LOCALTIME 0x80
> +#define LFMT_DEFAULT	LFMT_DEBUG
> +#define LFMT_SYSLOG_LOCAL	(LFMT_SYSLOG|LFMT_LOCALTIME)
> +#define LFMT_SYSLOG_UTC	(LFMT_SYSLOG)
> +#define LFMT_RFC3339_UTC	(LFMT_RFC3339)
> +
>  static slap_verbmasks logformat_key[] = {
>  	{ BER_BVC("default"),		LFMT_DEFAULT },
>  	{ BER_BVC("debug"),			LFMT_DEBUG },
>  	{ BER_BVC("syslog-utc"),	LFMT_SYSLOG_UTC },
>  	{ BER_BVC("syslog-localtime"),		LFMT_SYSLOG_LOCAL },
> +	{ BER_BVC("rfc3339-utc"),		LFMT_RFC3339_UTC },
>  	{ BER_BVNULL, 0 }
>  };
>  
> @@ -69,6 +76,13 @@
>  static int logpathlen;
>  
>  #define SYSLOG_STAMP	"Mmm dd hh:mm:ss"
> +#ifdef HAVE_CLOCK_GETTIME
> +#define RFC3339_FRAC	".fffffffffZ"
> +#else
> +#define RFC3339_FRAC	".ffffffZ"
> +#endif
> +#define RFC3339_BASE	"YYYY-mm-ddTHH:MM:SS"
> +#define RFC3339_STAMP	 RFC3339_BASE RFC3339_FRAC
>  
>  void
>  slap_debug_print( const char *data )
> @@ -84,11 +98,13 @@
>  #ifdef HAVE_CLOCK_GETTIME
>  	struct timespec tv;
>  #define	TS	"%08x"
> +#define	TSf	".%09ldZ"
>  #define	Tfrac	tv.tv_nsec
>  #define gettime(tv)	clock_gettime( CLOCK_REALTIME, tv )
>  #else
>  	struct timeval tv;
>  #define	TS	"%05x"
> +#define	TSf	".%06ldZ"
>  #define	Tfrac	tv.tv_usec
>  #define	gettime(tv)	gettimeofday( tv, NULL )
>  #endif
> @@ -171,7 +187,7 @@
>  
>  		if ( logfile_format > LFMT_DEBUG ) {
>  			struct tm tm;
> -			if ( logfile_format == LFMT_SYSLOG_UTC )
> +			if ( !( logfile_format & LFMT_LOCALTIME ) )
>  				ldap_pvt_gmtime( &tv.tv_sec, &tm );
>  			else
>  				ldap_pvt_localtime( &tv.tv_sec, &tm );
> @@ -182,9 +198,15 @@
>  #else
>  			ptr = syslog_prefix;
>  #endif
> -			strftime( ptr, sizeof( SYSLOG_STAMP ),
> -				"%b %d %H:%M:%S", &tm );
> -			ptr[ sizeof( SYSLOG_STAMP )-1 ] = ' ';
> +			if ( logfile_format & LFMT_SYSLOG ) {
> +				ptr += strftime( ptr, sizeof( SYSLOG_STAMP ),
> +					"%b %d %H:%M:%S", &tm );
> +			}	else {
> +				ptr += strftime( ptr, sizeof( RFC3339_BASE ),
> +					"%Y-%m-%dT%H:%M:%S", &tm );
> +				ptr += snprintf( ptr, sizeof( RFC3339_FRAC ), TSf, Tfrac );
> +			}
> +			*ptr = ' ';
>  #ifdef _WIN32
>  			len = datalen + splen;
>  #else
> @@ -814,11 +836,12 @@
>  			}
>  			if ( syslog_prefix )
>  				ch_free( syslog_prefix );
> -			len = strlen( global_host ) + 1 + strlen( serverName ) + 1 + sizeof("[123456789]:") +
> -				sizeof( SYSLOG_STAMP );
> -			syslog_prefix = ch_malloc( len );
> -			splen = sprintf( syslog_prefix, SYSLOG_STAMP " %s %s[%d]: ", global_host, serverName, getpid() );
>  			logfile_format = logformat_key[i].mask;
> +			len = strlen( global_host ) + 1 + strlen( serverName ) + 1 + sizeof(("[123456789]:")) +
> +				(( logfile_format & LFMT_RFC3339) ? sizeof( RFC3339_STAMP ) : sizeof( SYSLOG_STAMP ));
> +			syslog_prefix = ch_malloc( len );
> +			splen = sprintf( syslog_prefix, "%s %s %s[%d]: ", ( logfile_format & LFMT_RFC3339 ) ?
> +				RFC3339_STAMP : SYSLOG_STAMP, global_host, serverName, getpid() );
>  			}
>  			break;
>  
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/overlays/autoca.c openldap-2.6.10+dfsg/servers/slapd/overlays/autoca.c
> --- openldap-2.6.9+dfsg/servers/slapd/overlays/autoca.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/overlays/autoca.c	2025-05-22 10:56:21.000000000 -0700
> @@ -670,6 +670,7 @@
>  				else
>  					rc = 1;
>  			}
> +			break;
>  		case ACA_USRKEYBITS:
>  			if ( c->value_int < MIN_KEYBITS )
>  				rc = 1;
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/overlays/memberof.c openldap-2.6.10+dfsg/servers/slapd/overlays/memberof.c
> --- openldap-2.6.9+dfsg/servers/slapd/overlays/memberof.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/overlays/memberof.c	2025-05-22 10:56:21.000000000 -0700
> @@ -1301,10 +1301,8 @@
>  	if ( save_member ) {
>  		op->o_dn = op->o_bd->be_rootdn;
>  		op->o_ndn = op->o_bd->be_rootndn;
> -		op->o_bd->bd_info = (BackendInfo *)on->on_info;
>  		rc = backend_attribute( op, NULL, &op->o_req_ndn,
>  				mo->mo_ad_member, &mci->member, ACL_READ );
> -		op->o_bd->bd_info = (BackendInfo *)on;
>  	}
>  
>  	sc->sc_next = op->o_callback;
> @@ -1503,10 +1501,8 @@
>  
>  		case LDAP_MOD_REPLACE:
>  			/* delete all ... */
> -			op->o_bd->bd_info = (BackendInfo *)on->on_info;
>  			rc = backend_attribute( op, NULL, &op->o_req_ndn,
>  					mo->mo_ad_memberof, &vals, ACL_READ );
> -			op->o_bd->bd_info = (BackendInfo *)on;
>  			if ( rc == LDAP_SUCCESS ) {
>  				for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
>  					memberof_value_modify( op,
> @@ -1641,10 +1637,8 @@
>  	}
>  
>  	if ( mci->what & MEMBEROF_IS_GROUP ) {
> -		op->o_bd->bd_info = (BackendInfo *)on->on_info;
>  		rc = backend_attribute( op, NULL, &op->orr_nnewDN,
>  				mo->mo_ad_member, &vals, ACL_READ );
> -		op->o_bd->bd_info = (BackendInfo *)on;
>  
>  		if ( rc == LDAP_SUCCESS ) {
>  			for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
> @@ -1658,10 +1652,8 @@
>  	}
>  
>  	if ( MEMBEROF_REFINT( mo ) && ( mci->what & MEMBEROF_IS_MEMBER ) ) {
> -		op->o_bd->bd_info = (BackendInfo *)on->on_info;
>  		rc = backend_attribute( op, NULL, &op->orr_nnewDN,
>  				mo->mo_ad_memberof, &vals, ACL_READ );
> -		op->o_bd->bd_info = (BackendInfo *)on;
>  
>  		if ( rc == LDAP_SUCCESS ) {
>  			for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
> @@ -2159,6 +2151,15 @@
>  
>  		case MO_ADDCHECK:
>  			if ( c->value_int ) {
> +				if ( SLAP_ISGLOBALOVERLAY( c->be ) ) {
> +					snprintf( c->cr_msg, sizeof( c->cr_msg ),
> +						"addcheck functionality not supported "
> +						"when memberof is a global overlay",
> +						c->argv[ 1 ] );
> +					Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
> +						c->log, c->cr_msg );
> +					return 1;
> +				}
>  				mo->mo_flags |= MEMBEROF_FADDCHECK;
>  
>  			} else {
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/overlays/pcache.c openldap-2.6.10+dfsg/servers/slapd/overlays/pcache.c
> --- openldap-2.6.9+dfsg/servers/slapd/overlays/pcache.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/overlays/pcache.c	2025-05-22 10:56:21.000000000 -0700
> @@ -749,7 +749,7 @@
>  		}
>  	}
>  
> -	if ( got != GOT_ALL ) {
> +	if ( (got & GOT_ALL) != GOT_ALL) {
>  		rc = 1;
>  		goto error;
>  	}
> @@ -802,7 +802,11 @@
>  			goto error;
>  		}
>  
> -		cq = add_query( op, qm, &query, qt, PC_POSITIVE, 0 );
> +		if (BER_BVISNULL( &uuid )) {
> +		  cq = add_query( op, qm, &query, qt, PC_NEGATIVE, 0 );
> +		} else {
> +		  cq = add_query( op, qm, &query, qt, PC_POSITIVE, 0 );
> +		}
>  		if ( cq != NULL ) {
>  			cq->expiry_time = expiry_time;
>  			cq->refresh_time = refresh_time;
> @@ -1580,6 +1584,8 @@
>  
>  	case PC_NEGATIVE:
>  		ttl = templ->negttl;
> +		if ( templ->ttr )
> +			ttr = now + templ->ttr;
>  		break;
>  
>  	case PC_SIZELIMIT:
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/slapacl.c openldap-2.6.10+dfsg/servers/slapd/slapacl.c
> --- openldap-2.6.9+dfsg/servers/slapd/slapacl.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/slapacl.c	2025-05-22 10:56:21.000000000 -0700
> @@ -60,6 +60,18 @@
>  	return rc;
>  }
>  
> +static int
> +slapacl_entry_get(
> +	Operation *op,
> +	struct berval *dn,
> +	ObjectClass *oc,
> +	AttributeDescription *ad,
> +	int rw,
> +	Entry **e )
> +{
> +	return LDAP_UNWILLING_TO_PERFORM;
> +}
> +
>  int
>  slapacl( int argc, char **argv )
>  {
> @@ -293,6 +305,8 @@
>  				}
>  			}
>  		}
> +	} else {
> +		op->o_bd->be_fetch = slapacl_entry_get;
>  	}
>  
>  	for ( ; argc--; argv++ ) {
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/slapcommon.c openldap-2.6.10+dfsg/servers/slapd/slapcommon.c
> --- openldap-2.6.9+dfsg/servers/slapd/slapcommon.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/slapcommon.c	2025-05-22 10:56:21.000000000 -0700
> @@ -423,27 +423,42 @@
>  			rc = ldap_url_parse_ext( optarg, &ludp,
>  				LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_NOEMPTY_DN );
>  			if ( rc != LDAP_URL_SUCCESS ) {
> +				fprintf( stderr, "Cannot parse '%s' as LDAP URI.\n", optarg );
>  				usage( tool, progname );
>  			}
>  
>  			/* don't accept host, port, attrs, extensions */
>  			if ( ldap_pvt_url_scheme2proto( ludp->lud_scheme ) != LDAP_PROTO_TCP ) {
> +				fprintf( stderr, "%s URIs need to use ldap:// scheme.\n",
> +						progname );
>  				usage( tool, progname );
>  			}
>  
>  			if ( ludp->lud_host != NULL ) {
> +				fprintf( stderr, "%s URIs cannot carry a host. "
> +						"Only base, scope and filter are accepted\n",
> +						progname );
>  				usage( tool, progname );
>  			}
>  
>  			if ( ludp->lud_port != 0 ) {
> +				fprintf( stderr, "%s URIs cannot carry a port. "
> +						"Only base, scope and filter are accepted\n",
> +						progname );
>  				usage( tool, progname );
>  			}
>  
>  			if ( ludp->lud_attrs != NULL ) {
> +				fprintf( stderr, "%s URIs cannot carry an attribute specification. "
> +						"Only base, scope and filter are accepted\n",
> +						progname );
>  				usage( tool, progname );
>  			}
>  
>  			if ( ludp->lud_exts != NULL ) {
> +				fprintf( stderr, "%s URIs cannot carry an extension specification. "
> +						"Only base, scope and filter are accepted\n",
> +						progname );
>  				usage( tool, progname );
>  			}
>  
> @@ -465,6 +480,7 @@
>  
>  		case 'j':	/* jump to linenumber */
>  			if ( lutil_atoul( &jumpline, optarg ) ) {
> +				fprintf( stderr, "Invalid line number '%s'\n", optarg );
>  				usage( tool, progname );
>  			}
>  			break;
> @@ -479,6 +495,7 @@
>  
>  		case 'N':
>  			if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_NORMAL ) {
> +				fputs( "Invalid combination of -N/-P provided\n", stderr );
>  				usage( tool, progname );
>  			}
>  			dn_mode = SLAP_TOOL_LDAPDN_NORMAL;
> @@ -486,6 +503,7 @@
>  
>  		case 'n':	/* which config file db to index */
>  			if ( lutil_atoi( &dbnum, optarg ) || dbnum < 0 ) {
> +				fputs( "Invalid database index provided\n", stderr );
>  				usage( tool, progname );
>  			}
>  			break;
> @@ -498,6 +516,7 @@
>  
>  		case 'P':
>  			if ( dn_mode && dn_mode != SLAP_TOOL_LDAPDN_PRETTY ) {
> +				fputs( "Invalid combination of -N/-P provided\n", stderr );
>  				usage( tool, progname );
>  			}
>  			dn_mode = SLAP_TOOL_LDAPDN_PRETTY;
> @@ -520,6 +539,7 @@
>  			if ( lutil_atou( &csnsid, optarg )
>  				|| csnsid > SLAP_SYNC_SID_MAX )
>  			{
> +				fputs( "Invalid serverid provided\n", stderr );
>  				usage( tool, progname );
>  			}
>  			break;
> diff -Nru openldap-2.6.9+dfsg/servers/slapd/syncrepl.c openldap-2.6.10+dfsg/servers/slapd/syncrepl.c
> --- openldap-2.6.9+dfsg/servers/slapd/syncrepl.c	2024-11-26 09:11:04.000000000 -0800
> +++ openldap-2.6.10+dfsg/servers/slapd/syncrepl.c	2025-05-22 10:56:21.000000000 -0700
> @@ -2793,7 +2793,6 @@
>  
>  typedef struct modify_ctxt {
>  	Modifications *mx_orig;
> -	Modifications *mx_free;
>  	Entry *mx_entry;
>  } modify_ctxt;
>  
> @@ -2805,11 +2804,8 @@
>  	Modifications *ml;
>  
>  	op->orm_no_opattrs = 0;
> +	slap_mods_free( op->orm_modlist, 0 );
>  	op->orm_modlist = mx->mx_orig;
> -	for ( ml = mx->mx_free; ml; ml = mx->mx_free ) {
> -		mx->mx_free = ml->sml_next;
> -		op->o_tmpfree( ml, op->o_tmpmemctx );
> -	}
>  	if ( mx->mx_entry ) {
>  		entry_free( mx->mx_entry );
>  	}
> @@ -2997,10 +2993,10 @@
>  		sc->sc_next = op->o_callback;
>  		sc->sc_cleanup = NULL;
>  		sc->sc_writewait = NULL;
> -		op->o_callback = sc;
> +		overlay_callback_after_backover( op, sc, 1 );
> +
>  		op->orm_no_opattrs = 1;
>  		mx->mx_orig = op->orm_modlist;
> -		mx->mx_free = newlist;
>  		mx->mx_entry = e_dup;
>  		for ( ml = newlist; ml; ml=ml->sml_next ) {
>  			if ( ml->sml_flags == SLAP_MOD_INTERNAL ) {


-- 
Sebastian Ramacher


Reply to: