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 = ≻
> + 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 = ≻
> + 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 = ≻
> + 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 = ≻
> + 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: