[Pkg-freeipa-devel] [Git][freeipa-team/389-ds-base][upstream] 18 commits: missing clang formatting in urp_tombstone

Timo Aaltonen gitlab at salsa.debian.org
Fri Jun 1 09:46:23 BST 2018


Timo Aaltonen pushed to branch upstream at FreeIPA packaging / 389-ds-base


Commits:
81a9d757 by Ludwig Krispenz at 2018-03-08T14:20:05+01:00
missing clang formatting in urp_tombstone

- - - - -
485cf0c6 by Mark Reynolds at 2018-03-16T09:02:36-04:00
Ticket 49599 - Revise replication total init status messages

Description:  Previously the replication update status messages were
              updated to a more readable format.  This should also be
              done with the total update status messages.

https://pagure.io/389-ds-base/issue/49599

Reviewed by: lkrispen(Thanks!)

(cherry picked from commit b67f0f822911d0abd4467734a7150c6a94635b82)

- - - - -
d5e2f749 by Thierry Bordaz at 2018-03-23T16:02:11+01:00
Ticket 49619 - adjustment of csn_generator can fail so next generated csn can be equal to the most recent one received

Bug Description:
	On consumer side csn_generator ajustment occurs (let CSN = highest known csn)

	    when a replication session starts
	    when a csn is generated locally and than csn is <= CSN

	During adjustment, in the case

	    there is no remote/local offset (time change)
	    the current_time on the consumer is identical to CSN

	Then next locally generated csn will only differ with seqnum

	The seqnum of the csn_generator is increased only if CSN.seqnum is larger
	than the csn_generator one.
	In case of egality, it remains unchanged.

	The consequence is that the next locally generated csn will be identical to CSN (except for the RID).
	So even after csn_generator adjustment, csn_generator may create csn that are not larger than the CSN

Fix Description:
	compare the new generated timestamp (time+offsets) with adjustment one.
	If the new is greater or EQUAL, make sure the local seqnum is ahead the remote one

https://pagure.io/389-ds-base/issue/49619

Reviewed by: Mark Reynolds

Platforms tested: F27

Flag Day: no

Doc impact: no

- - - - -
65d0e49b by Mark Reynolds at 2018-03-26T12:24:28-04:00
Rebase to 1.3.8

- - - - -
804002e1 by Mark Reynolds at 2018-03-29T13:53:38-04:00
Ticket 48184 - revert previous patch around unuc-stans shutdown crash

https://pagure.io/389-ds-base/issue/48184

- - - - -
acd3a91d by Ludwig Krispenz at 2018-04-05T10:28:19+02:00
Ticket 49631 - same csn generated twice

Bug: if in the csn adjustment the local time was less or equal than the remote time
     the sequence number has always been adjusted to remote++
     but if the csn time was equal and the local seq number was larger the effect
     was a reset of the csn generato.

Fix: correctly handles seqnum in csn adjustment

Reviewed by: Mark, thanks

- - - - -
8505cb8b by Mark Reynolds at 2018-04-20T11:08:45-04:00
Ticket 49644 - crash in debug build

Description:  In a debug build of the server it crashes when searching
              the cn=config.  This is due to a pointer not being initialized
              before being dereferenced.

https://pagure.io/389-ds-base/issue/49644

Reviewed by: mreynolds(one line commit rule)

(cherry picked from commit 5bfc18a245405229bd7bd2acfee681e68df338d6)

- - - - -
183bacdd by Mark Reynolds at 2018-04-24T11:02:02-04:00
Ticket 49649 - Use reentrant crypt_r()

Bug Description:  We were previously using crypt() which is not
                  thread safe and reuired a lock.  Using pwdhash cli
                  tool caused a crash because the lock was not created
                  when invoked by the cli.

Fix Description:  Use crypt_r() instead which does not require any locking.

https://pagure.io/389-ds-base/issue/49649

Reviewed by: Simon(Thanks!)

(cherry picked from commit 530a2db1776fca545436cbac2987f6b86f6c7048)

- - - - -
eb08d435 by Mark Reynolds at 2018-04-27T08:59:18-04:00
Ticket 49652 - DENY aci's are not handled properly

Bug Description:  There are really two issues here.  One, when a resource
                  is denied by a DENY aci the cached results for that resource
                  are not proprely set, and on the same connection if the same
                  operation repeated it will be allowed instead of denied because
                  the cache result was not proprely updated.

                  Two, if there are no ALLOW aci's on a resource, then we don't
                  check the deny rules, and resources that are restricted are
                  returned to the client.

Fix Description:  For issue one, when an entry is denied access reset all the
                  attributes' cache results to DENIED as it's possible previously
                  evaluated aci's granted access to some of these attributes which
                  are still present in the acl result cache.

                  For issue two, if there are no ALLOW aci's on a resource but
                  there are DENY aci's, then set the aclpb state flags to
                  process DENY aci's

https://pagure.io/389-ds-base/issue/49652

Reviewed by: tbordaz & lkrispenz(Thanks!!)

(cherry picked from commit d77c7f0754f67022b42784c05be8a493a00f2ec5)

- - - - -
a5890087 by Mark Reynolds at 2018-05-08T10:54:01-04:00
CVE-2018-1089 - Crash from long search filter

Signed-off-by: Mark Reynolds <mreynolds at redhat.com>
(cherry picked from commit 9d8d096b154e44f3e1fa1f8d5bfe258ed8d9dc51)

- - - - -
2817f0c4 by Mark Reynolds at 2018-05-08T12:35:43-04:00
Ticket 49649

Description:  Fix crpyt.h include

https://pagure.io/389-ds-base/issue/49649

Reviewed by: mreynolds(one line commit rule)

- - - - -
90ca2eba by Mark Reynolds at 2018-05-08T12:40:15-04:00
Bump version to 1.3.8.1

- - - - -
b535e288 by Mark Reynolds at 2018-05-10T08:03:56-04:00
Ticket 49665 - Upgrade script doesn't enable PBKDF2 password storage plug-in

Description:  There is no upgrade script to add the PBKDF2 plugin, this
              fix adds the script.

https://pagure.io/389-ds-base/issue/49665

Reviewed by: ?

(cherry picked from commit dc690dd231a626b3b6a2019fee51e3cb15db7962)

- - - - -
89a9de99 by Mark Reynolds at 2018-05-10T08:04:02-04:00
Ticket 49665 - Upgrade script doesn't enable CRYPT password storage plug-in

Description:  There is no upgrade script to add the new CRYPT plugins, this
              fix adds the script.

https://pagure.io/389-ds-base/issue/49665

Reviewed by: vashirov(Thanks!)

(cherry picked from commit 91dc832411a1bb6e8bf62bb72c36777ddc63770f)

- - - - -
de9fb252 by Mark Reynolds at 2018-05-13T15:04:08-04:00
Ticket 49671 - Readonly replicas should not write internal ops to changelog

Bug Description:  When a hub receives an update that triggers the memberOf
                  plugin, but that interal operation has no csn and that
                  causes the update to the changelog to fail and break
                  replication.

Fix Description:  Do not write internal updates with no csns to the changelog
                  on read-only replicas.

https://pagure.io/389-ds-base/issue/49671

Reviewed by: simon, tbordaz, and lkrispen (Thanks!!!)

(cherry picked from commit afb755bd95f1643665ea34c5a5fa2bb26bfa21b9)

- - - - -
40178b51 by Ludwig Krispenz at 2018-05-17T11:40:45+02:00
    Ticket 49696: replicated operations should be serialized

    Bug: there was a scenario where two threads could process replication operations in parallel.
         The reason was that for a new repl start request the repl conn flag is not set and the
         connection is made readable.
         When the start repl op is finished, the flagi set, but in a small window the supplier could
         already have sent updates and more_data would trigger this thread also to continue to process
         repl operations.

    Fix: In the situation where a thread successfully processed a start repl request and just set the repl_conn
         flag  do not use more_data.

    Reviewed by: Thierry, thanks

- - - - -
941360ba by Thierry Bordaz at 2018-05-21T14:02:11-04:00
Ticket 48184 - clean up and delete connections at shutdown (2nd try)

Bug description:
    During shutdown we would not close connections.
    In the past this may have just been an annoyance, but now with the way
    nunc-stans works, io events can still trigger on open xeisting connectinos
    during shutdown.

    Because of NS dynamic it can happen that several jobs wants to work on the
    same connection. In such case (a job is already set in c_job) we delay the
    new job that will retry.
    In addition:
	- some call needed c_mutex
	- test uninitialized nunc-stans in case of shutdown while startup is not completed

Fix Description:  Close connections during shutdown rather than
    leaving them alive.

https://pagure.io/389-ds-base/issue/48184

Reviewed by:
	Original was Ludwig and Viktor
	Second fix reviewed by Mark

Platforms tested: F26

Flag Day: no

Doc impact: no

(cherry picked from commit e562157ca3e97867d902996cc18fb04f90dc10a8)

- - - - -
21800c3c by Mark Reynolds at 2018-05-24T11:46:17-04:00
Bump version to 1.3.8.2

- - - - -


20 changed files:

- Makefile.am
- VERSION.sh
- + dirsrvtests/tests/suites/acl/acl_deny_test.py
- + dirsrvtests/tests/suites/replication/cascading_test.py
- + ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
- + ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
- ldap/servers/plugins/acl/acl.c
- ldap/servers/plugins/pwdstorage/crypt_pwd.c
- ldap/servers/plugins/pwdstorage/pwd_init.c
- ldap/servers/plugins/pwdstorage/pwdstorage.h
- ldap/servers/plugins/replication/repl5_agmt.c
- ldap/servers/plugins/replication/repl5_plugins.c
- ldap/servers/plugins/replication/urp_tombstone.c
- ldap/servers/slapd/back-ldbm/monitor.c
- ldap/servers/slapd/connection.c
- ldap/servers/slapd/csngen.c
- ldap/servers/slapd/daemon.c
- ldap/servers/slapd/filter.c
- ldap/servers/slapd/slap.h
- ldap/servers/slapd/util.c


Changes:

=====================================
Makefile.am
=====================================
--- a/Makefile.am
+++ b/Makefile.am
@@ -952,6 +952,8 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50refintprecedence.ldif \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/50rootdnaccesscontrolplugin.ldif \
+	ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif \
+	ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif \
 	ldap/admin/src/scripts/50contentsync.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/60upgradeconfigfiles.pl \


=====================================
VERSION.sh
=====================================
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
 # PACKAGE_VERSION is constructed from these
 VERSION_MAJOR=1
 VERSION_MINOR=3
-VERSION_MAINT=7.10
+VERSION_MAINT=8.2
 # NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
 VERSION_PREREL=
 VERSION_DATE=$(date -u +%Y%m%d)


=====================================
dirsrvtests/tests/suites/acl/acl_deny_test.py
=====================================
--- /dev/null
+++ b/dirsrvtests/tests/suites/acl/acl_deny_test.py
@@ -0,0 +1,198 @@
+import logging
+import pytest
+import os
+import ldap
+import time
+from lib389._constants import *
+from lib389.topologies import topology_st as topo
+from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES
+from lib389.idm.domain import Domain
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+    logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+BIND_DN2 = 'uid=tuser,ou=People,dc=example,dc=com'
+BIND_RDN2 = 'tuser'
+BIND_DN = 'uid=tuser1,ou=People,dc=example,dc=com'
+BIND_RDN = 'tuser1'
+SRCH_FILTER = "uid=tuser1"
+SRCH_FILTER2 = "uid=tuser"
+
+aci_list_A = ['(targetattr != "userPassword") (version 3.0; acl "Anonymous access"; allow (read, search, compare)userdn = "ldap:///anyone";)',
+              '(targetattr = "*") (version 3.0;acl "allow tuser";allow (all)(userdn = "ldap:///uid=tuser5,ou=People,dc=example,dc=com");)',
+              '(targetattr != "uid || mail") (version 3.0; acl "deny-attrs"; deny (all) (userdn = "ldap:///anyone");)',
+              '(targetfilter = "(inetUserStatus=1)") ( version 3.0; acl "deny-specific-entry"; deny(all) (userdn = "ldap:///anyone");)']
+
+aci_list_B = ['(targetattr != "userPassword") (version 3.0; acl "Anonymous access"; allow (read, search, compare)userdn = "ldap:///anyone";)',
+              '(targetattr != "uid || mail") (version 3.0; acl "deny-attrs"; deny (all) (userdn = "ldap:///anyone");)',
+              '(targetfilter = "(inetUserStatus=1)") ( version 3.0; acl "deny-specific-entry"; deny(all) (userdn = "ldap:///anyone");)']
+
+
+ at pytest.fixture(scope="module")
+def aci_setup(topo):
+    topo.standalone.log.info("Add {}".format(BIND_DN))
+    user = UserAccount(topo.standalone, BIND_DN)
+    user_props = TEST_USER_PROPERTIES.copy()
+    user_props.update({'sn': BIND_RDN,
+                       'cn': BIND_RDN,
+                       'uid': BIND_RDN,
+                       'inetUserStatus': '1',
+                       'objectclass': 'extensibleObject',
+                       'userpassword': PASSWORD})
+    user.create(properties=user_props, basedn=SUFFIX)
+
+    topo.standalone.log.info("Add {}".format(BIND_DN2))
+    user2 = UserAccount(topo.standalone, BIND_DN2)
+    user_props = TEST_USER_PROPERTIES.copy()
+    user_props.update({'sn': BIND_RDN2,
+                       'cn': BIND_RDN2,
+                       'uid': BIND_RDN2,
+                       'userpassword': PASSWORD})
+    user2.create(properties=user_props, basedn=SUFFIX)
+
+
+def test_multi_deny_aci(topo, aci_setup):
+    """Test that mutliple deny rules work, and that they the cache properly
+    stores the result
+
+    :id: 294c366d-850e-459e-b5a0-3cc828ec3aca
+    :setup: Standalone Instance
+    :steps:
+        1. Add aci_list_A aci's and verify two searches on the same connection
+           behave the same
+        2. Add aci_list_B aci's and verify search fails as expected
+    :expectedresults:
+        1. Both searches do not return any entries
+        2. Seaches do not return any entries
+    """
+
+    if DEBUGGING:
+        # Maybe add aci logging?
+        pass
+
+    suffix = Domain(topo.standalone, DEFAULT_SUFFIX)
+
+    for run in range(2):
+        topo.standalone.log.info("Pass " + str(run + 1))
+
+        # Test ACI List A
+        topo.standalone.log.info("Testing two searches behave the same...")
+        topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+        suffix.set('aci', aci_list_A, ldap.MOD_REPLACE)
+        time.sleep(1)
+
+        topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user")
+            assert False
+
+        # Bind a different user who has rights
+        topo.standalone.simple_bind_s(BIND_DN2, PASSWORD)
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user (2)")
+            assert False
+
+        if run > 0:
+            # Second pass
+            topo.standalone.restart()
+
+        # Reset ACI's and do the second test
+        topo.standalone.log.info("Testing search does not return any entries...")
+        topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+        suffix.set('aci', aci_list_B, ldap.MOD_REPLACE)
+        time.sleep(1)
+
+        topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+            assert False
+
+        if run > 0:
+            # Second pass
+            topo.standalone.restart()
+
+        # Bind as different user who has rights
+        topo.standalone.simple_bind_s(BIND_DN2, PASSWORD)
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as good user (2)")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+            assert False
+
+        # back to user 1
+        topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as user1")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+        if entries is None or len(entries) == 0:
+            topo.standalone.log.fatal("Failed to get entry as user1 (2)")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+            assert False
+
+        entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+        if entries and entries[0]:
+            topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+            assert False
+
+    topo.standalone.log.info("Test PASSED")
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main(["-s", CURRENT_FILE])
+


=====================================
dirsrvtests/tests/suites/replication/cascading_test.py
=====================================
--- /dev/null
+++ b/dirsrvtests/tests/suites/replication/cascading_test.py
@@ -0,0 +1,150 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2018 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+import pytest
+import os
+import ldap
+from lib389._constants import *
+from lib389.replica import ReplicationManager
+from lib389.plugins import MemberOfPlugin
+from lib389.agreement import Agreements
+from lib389.idm.user import UserAccount, TEST_USER_PROPERTIES
+from lib389.idm.group import Groups
+from lib389.topologies import topology_m1h1c1 as topo
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+    logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+BIND_DN = 'uid=tuser1,ou=People,dc=example,dc=com'
+BIND_RDN = 'tuser1'
+
+
+def config_memberof(server):
+    """Configure memberOf plugin and configure fractional
+    to prevent total init to send memberof
+    """
+
+    memberof = MemberOfPlugin(server)
+    memberof.enable()
+    memberof.set_autoaddoc('nsMemberOf')
+    server.restart()
+    agmts = Agreements(server)
+    for agmt in agmts.list():
+        log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % agmt.dn)
+        agmt.replace_many(('nsDS5ReplicatedAttributeListTotal', '(objectclass=*) $ EXCLUDE '),
+                          ('nsDS5ReplicatedAttributeList', '(objectclass=*) $ EXCLUDE memberOf'))
+
+
+def test_basic_with_hub(topo):
+    """Check that basic operations work in cascading replication, this includes
+    testing plugins that perform internal operatons, and replicated password
+    policy state attributes.
+
+    :id: 4ac85552-45bc-477b-89a4-226dfff8c6cc
+    :setup: 1 master, 1 hub, 1 consumer
+    :steps:
+        1. Enable memberOf plugin and set password account lockout settings
+        2. Restart the instance
+        3. Add a user
+        4. Add a group
+        5. Test that the replication works
+        6. Add the user as a member to the group
+        7. Test that the replication works
+        8. Issue bad binds to update passwordRetryCount
+        9. Test that replicaton works
+        10. Check that passwordRetyCount was replicated
+    :expectedresults:
+        1. Should be a success
+        2. Should be a success
+        3. Should be a success
+        4. Should be a success
+        5. Should be a success
+        6. Should be a success
+        7. Should be a success
+        8. Should be a success
+        9. Should be a success
+        10. Should be a success
+    """
+
+    repl_manager = ReplicationManager(DEFAULT_SUFFIX)
+    master = topo.ms["master1"]
+    consumer = topo.cs["consumer1"]
+    hub = topo.hs["hub1"]
+
+    for inst in topo:
+        config_memberof(inst)
+        inst.config.set('passwordlockout', 'on')
+        inst.config.set('passwordlockoutduration', '60')
+        inst.config.set('passwordmaxfailure', '3')
+        inst.config.set('passwordIsGlobalPolicy', 'on')
+
+    # Create user
+    user1 = UserAccount(master, BIND_DN)
+    user_props = TEST_USER_PROPERTIES.copy()
+    user_props.update({'sn': BIND_RDN,
+                       'cn': BIND_RDN,
+                       'uid': BIND_RDN,
+                       'inetUserStatus': '1',
+                       'objectclass': 'extensibleObject',
+                       'userpassword': PASSWORD})
+    user1.create(properties=user_props, basedn=SUFFIX)
+
+    # Create group
+    groups = Groups(master, DEFAULT_SUFFIX)
+    group = groups.create(properties={'cn': 'group'})
+
+    # Test replication
+    repl_manager.test_replication(master, consumer)
+
+    # Trigger memberOf plugin by adding user to group
+    group.replace('member', user1.dn)
+
+    # Test replication once more
+    repl_manager.test_replication(master, consumer)
+
+    # Issue bad password to update passwordRetryCount
+    try:
+        master.simple_bind_s(user1.dn, "badpassword")
+    except:
+        pass
+
+    # Test replication one last time
+    master.simple_bind_s(DN_DM, PASSWORD)
+    repl_manager.test_replication(master, consumer)
+
+    # Finally check if passwordRetyCount was replicated to the hub and consumer
+    user1 = UserAccount(hub, BIND_DN)
+    count = user1.get_attr_val_int('passwordRetryCount')
+    if count is None:
+        log.fatal('PasswordRetyCount was not replicated to hub')
+        assert False
+    if int(count) != 1:
+        log.fatal('PasswordRetyCount has unexpected value: {}'.format(count))
+        assert False
+
+    user1 = UserAccount(consumer, BIND_DN)
+    count = user1.get_attr_val_int('passwordRetryCount')
+    if count is None:
+        log.fatal('PasswordRetyCount was not replicated to consumer')
+        assert False
+    if int(count) != 1:
+        log.fatal('PasswordRetyCount has unexpected value: {}'.format(count))
+        assert False
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main(["-s", CURRENT_FILE])
+


=====================================
ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
=====================================
--- /dev/null
+++ b/ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
@@ -0,0 +1,38 @@
+dn: cn=CRYPT-MD5,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-MD5
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_md5_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
+
+dn: cn=CRYPT-SHA256,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-SHA256
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_sha256_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
+
+dn: cn=CRYPT-SHA512,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-SHA512
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_sha512_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC


=====================================
ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
=====================================
--- /dev/null
+++ b/ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
@@ -0,0 +1,12 @@
+dn: cn=PBKDF2_SHA256,cn=Password Storage Schemes,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+cn: PBKDF2_SHA256
+nsslapd-pluginpath: libpwdstorage-plugin
+nsslapd-plugininitfunc: pbkdf2_sha256_pwd_storage_scheme_init
+nsslapd-plugintype: pwdstoragescheme
+nsslapd-pluginenabled: on
+nsslapd-pluginDescription: DESC
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginid: ID


=====================================
ldap/servers/plugins/acl/acl.c
=====================================
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -1088,9 +1088,23 @@ acl_read_access_allowed_on_entry(
                     ** a DENY rule, then we don't have access to
                     ** the entry ( nice trick to get in )
                     */
-                    if (aclpb->aclpb_state &
-                        ACLPB_EXECUTING_DENY_HANDLES)
+                    if (aclpb->aclpb_state & ACLPB_EXECUTING_DENY_HANDLES) {
+                        aclEvalContext *c_ContextEval = &aclpb->aclpb_curr_entryEval_context;
+                        AclAttrEval *c_attrEval = NULL;
+                        /*
+                         * The entire entry is blocked, but previously evaluated allow aci's might
+                         * show some of the attributes as readable in the acl cache, so reset all
+                         * the cached attributes' status to FAIL.
+                         */
+                        for (size_t j = 0; j < c_ContextEval->acle_numof_attrs; j++) {
+                            c_attrEval = &c_ContextEval->acle_attrEval[j];
+                            c_attrEval->attrEval_r_status &= ~ACL_ATTREVAL_SUCCESS;
+                            c_attrEval->attrEval_r_status |= ACL_ATTREVAL_FAIL;
+                            c_attrEval->attrEval_s_status &= ~ACL_ATTREVAL_SUCCESS;
+                            c_attrEval->attrEval_s_status |= ACL_ATTREVAL_FAIL;
+                        }
                         return LDAP_INSUFFICIENT_ACCESS;
+                    }
 
                     /* The other case is I don't have an
                     ** explicit allow rule -- which is fine.
@@ -2908,6 +2922,12 @@ acl__TestRights(Acl_PBlock *aclpb, int access, const char **right, const char **
         result_reason->deciding_aci = NULL;
         result_reason->reason = ACL_REASON_NO_MATCHED_RESOURCE_ALLOWS;
 
+        /* If we have deny handles we should process them */
+        if (aclpb->aclpb_num_deny_handles > 0) {
+            aclpb->aclpb_state &= ~ACLPB_EXECUTING_ALLOW_HANDLES;
+            aclpb->aclpb_state |= ACLPB_EXECUTING_DENY_HANDLES;
+        }
+
         TNF_PROBE_1_DEBUG(acl__TestRights_end, "ACL", "",
                           tnf_string, no_allows, "");
 


=====================================
ldap/servers/plugins/pwdstorage/crypt_pwd.c
=====================================
--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
@@ -20,19 +20,9 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#if defined(hpux) || defined(LINUX) || defined(__FreeBSD__)
-#ifndef __USE_XOPEN
-#define __USE_XOPEN /* linux */
-#endif              /* __USE_XOPEN */
-#include <unistd.h>
-#else /* hpux */
-#include <crypt.h>
-#endif /* hpux */
-
+#include <crypt.h>  /* for crypt_r */
 #include "pwdstorage.h"
 
-static PRLock *cryptlock = NULL; /* Some implementations of crypt are not thread safe.  ie. ours & Irix */
-
 /* characters used in crypt encoding */
 static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -44,38 +34,20 @@ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
 
 
 int
-crypt_start(Slapi_PBlock *pb __attribute__((unused)))
-{
-    if (!cryptlock) {
-        cryptlock = PR_NewLock();
-    }
-    return 0;
-}
-
-int
-crypt_close(Slapi_PBlock *pb __attribute__((unused)))
-{
-    if (cryptlock) {
-        PR_DestroyLock(cryptlock);
-        cryptlock = NULL;
-    }
-    return 0;
-}
-
-int
 crypt_pw_cmp(const char *userpwd, const char *dbpwd)
 {
     int rc;
     char *cp;
-    PR_Lock(cryptlock);
-    /* we use salt (first 2 chars) of encoded password in call to crypt() */
-    cp = crypt(userpwd, dbpwd);
+    struct crypt_data data;
+    data.initialized = 0;
+
+    /* we use salt (first 2 chars) of encoded password in call to crypt_r() */
+    cp = crypt_r(userpwd, dbpwd, &data);
     if (cp) {
         rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd));
     } else {
         rc = -1;
     }
-    PR_Unlock(cryptlock);
     return rc;
 }
 
@@ -88,6 +60,8 @@ crypt_pw_enc_by_hash(const char *pwd, int hash_algo)
     char *enc = NULL;
     long v;
     static unsigned int seed = 0;
+    struct crypt_data data;
+    data.initialized = 0;
 
     if (seed == 0) {
         seed = (unsigned int)slapi_rand();
@@ -113,12 +87,10 @@ crypt_pw_enc_by_hash(const char *pwd, int hash_algo)
         algo_salt = strdup(salt);
     }
 
-    PR_Lock(cryptlock);
-    cry = crypt(pwd, algo_salt);
+    cry = crypt_r(pwd, algo_salt, &data);
     if (cry != NULL) {
         enc = slapi_ch_smprintf("%c%s%c%s", PWD_HASH_PREFIX_START, CRYPT_SCHEME_NAME, PWD_HASH_PREFIX_END, cry);
     }
-    PR_Unlock(cryptlock);
     slapi_ch_free_string(&algo_salt);
 
     return (enc);


=====================================
ldap/servers/plugins/pwdstorage/pwd_init.c
=====================================
--- a/ldap/servers/plugins/pwdstorage/pwd_init.c
+++ b/ldap/servers/plugins/pwdstorage/pwd_init.c
@@ -245,8 +245,6 @@ crypt_pwd_storage_scheme_init(Slapi_PBlock *pb)
                           (void *)SLAPI_PLUGIN_VERSION_01);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                            (void *)&crypt_pdesc);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
                            (void *)crypt_pw_enc);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -269,8 +267,6 @@ crypt_md5_pwd_storage_scheme_init(Slapi_PBlock *pb)
                           (void *)SLAPI_PLUGIN_VERSION_01);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                            (void *)&crypt_md5_pdesc);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
                            (void *)crypt_pw_md5_enc);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -293,8 +289,6 @@ crypt_sha256_pwd_storage_scheme_init(Slapi_PBlock *pb)
                           (void *)SLAPI_PLUGIN_VERSION_01);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                            (void *)&crypt_sha256_pdesc);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
                            (void *)crypt_pw_sha256_enc);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -317,8 +311,6 @@ crypt_sha512_pwd_storage_scheme_init(Slapi_PBlock *pb)
                           (void *)SLAPI_PLUGIN_VERSION_01);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                            (void *)&crypt_sha512_pdesc);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
-    rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
                            (void *)crypt_pw_sha512_enc);
     rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,


=====================================
ldap/servers/plugins/pwdstorage/pwdstorage.h
=====================================
--- a/ldap/servers/plugins/pwdstorage/pwdstorage.h
+++ b/ldap/servers/plugins/pwdstorage/pwdstorage.h
@@ -74,8 +74,6 @@ char *sha512_pw_enc(const char *pwd);
 char *salted_sha512_pw_enc(const char *pwd);
 int clear_pw_cmp(const char *userpwd, const char *dbpwd);
 char *clear_pw_enc(const char *pwd);
-int crypt_start(Slapi_PBlock *pb);
-int crypt_close(Slapi_PBlock *pb);
 int crypt_pw_cmp(const char *userpwd, const char *dbpwd);
 char *crypt_pw_enc(const char *pwd);
 char *crypt_pw_md5_enc(const char *pwd);


=====================================
ldap/servers/plugins/replication/repl5_agmt.c
=====================================
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2523,7 +2523,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
                     replmsg = NULL;
                 }
             }
-            PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s%s%s",
+            PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s%sLDAP error: %s%s%s%s%s",
                         ldaprc, message ? message : "", message ? "" : " - ",
                         slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "",
                         connrc ? " - " : "", connrc ? connmsg : "");
@@ -2531,7 +2531,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
         /* ldaprc == LDAP_SUCCESS */
         else if (replrc != 0) {
             if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) {
-                PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s",
+                PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s",
                             ldaprc, "Replication session successful");
             } else if (replrc == NSDS50_REPL_DISABLED) {
                 if (agmt_is_enabled(ra)) {
@@ -2539,7 +2539,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
                                                                    "Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n"
                                                                    "You must enable it then restart the server for replication to take place).\n",
                                   ra->long_name ? ra->long_name : "a replica");
-                    PR_snprintf(ra->last_init_status, STATUS_LEN, "%d Total update aborted: "
+                    PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: "
                                                                   "Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n"
                                                                   "You must enable it then restart the server for replication to take place).",
                                 replrc, ra->long_name ? ra->long_name : "a replica");
@@ -2548,29 +2548,29 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
                     slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: "
                                                                    "Replication agreement for \"%s\" can not be updated while the agreement is disabled\n",
                                   ra->long_name ? ra->long_name : "a replica");
-                    PR_snprintf(ra->last_init_status, STATUS_LEN, "%d Total update aborted: "
+                    PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: "
                                                                   "Replication agreement for \"%s\" can not be updated while the agreement is disabled.",
                                 replrc, ra->long_name ? ra->long_name : "a replica");
                 }
             } else {
                 PR_snprintf(ra->last_init_status, STATUS_LEN,
-                            "%d Replication error acquiring replica: %s%s%s%s%s",
+                            "Error (%d) Replication error acquiring replica: %s%s%s%s%s",
                             replrc, protocol_response2string(replrc),
                             message ? " - " : "", message ? message : "",
                             connrc ? " - " : "", connrc ? connmsg : "");
             }
         } else if (connrc != CONN_OPERATION_SUCCESS) {
             PR_snprintf(ra->last_init_status, STATUS_LEN,
-                        "%d connection error: %s%s%s",
+                        "Error (%d) connection error: %s%s%s",
                         connrc, connmsg,
                         message ? " - " : "", message ? message : "");
         } else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
         {
             PR_snprintf(ra->last_init_status, STATUS_LEN,
-                        "%d %s",
+                        "Error (%d) %s",
                         ldaprc, message);
         } else { /* agmt_set_last_init_status(0,0,NULL) to reset agmt */
-            PR_snprintf(ra->last_init_status, STATUS_LEN, "%d", ldaprc);
+            PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)", ldaprc);
         }
     }
 }


=====================================
ldap/servers/plugins/replication/repl5_plugins.c
=====================================
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1059,6 +1059,16 @@ write_changelog_and_ruv(Slapi_PBlock *pb)
             goto common_return;
         }
 
+        /* Skip internal operations with no op csn if this is a read-only replica */
+        if (op_params->csn == NULL &&
+            operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
+            replica_get_type(r) == REPLICA_TYPE_READONLY)
+        {
+            slapi_log_err(SLAPI_LOG_REPL, "write_changelog_and_ruv",
+                          "Skipping internal operation on read-only replica\n");
+            goto common_return;
+        }
+
         /* we might have stripped all the mods - in that case we do not
            log the operation */
         if (op_params->operation_type != SLAPI_OPERATION_MODIFY ||


=====================================
ldap/servers/plugins/replication/urp_tombstone.c
=====================================
--- a/ldap/servers/plugins/replication/urp_tombstone.c
+++ b/ldap/servers/plugins/replication/urp_tombstone.c
@@ -51,97 +51,94 @@ get_tombstone_csn(const Slapi_Entry *entry, const CSN **delcsn)
     return ists;
 }
 
-static Slapi_DN*
+static Slapi_DN *
 get_valid_parent_for_conflict(Slapi_Entry *entry)
 {
-	char *replconflict = slapi_entry_attr_get_charptr(entry,ATTR_NSDS5_REPLCONFLICT );
-	char *validdn = NULL;
-	Slapi_DN *valid_DN = NULL;
-
-	if (replconflict) {
-		validdn = strstr(replconflict, " (ADD) ");
-		if (validdn) {
-			validdn += 7;
-			valid_DN = slapi_sdn_new_dn_byval(validdn);
-			slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
-				"get_valid_parent_for_conflict - valid entry dn: %s\n",
-				validdn);
-		}
-		slapi_ch_free_string(&replconflict);
-	}
-	return valid_DN;
+    char *replconflict = slapi_entry_attr_get_charptr(entry, ATTR_NSDS5_REPLCONFLICT);
+    char *validdn = NULL;
+    Slapi_DN *valid_DN = NULL;
+
+    if (replconflict) {
+        validdn = strstr(replconflict, " (ADD) ");
+        if (validdn) {
+            validdn += 7;
+            valid_DN = slapi_sdn_new_dn_byval(validdn);
+            slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+                          "get_valid_parent_for_conflict - valid entry dn: %s\n",
+                          validdn);
+        }
+        slapi_ch_free_string(&replconflict);
+    }
+    return valid_DN;
 }
 
 int
-tombstone_to_conflict_check_parent (
-	char *sessionid,
-	char *parentdn,
-	const char *uniqueid,
-	const char *parentuniqueid,
-	CSN *opcsn,
-	Slapi_DN *conflictdn)
+tombstone_to_conflict_check_parent(
+    char *sessionid,
+    char *parentdn,
+    const char *uniqueid,
+    const char *parentuniqueid,
+    CSN *opcsn,
+    Slapi_DN *conflictdn)
 {
-	int rc = 0;
-	int op_result;
-	Slapi_PBlock *newpb;
-
-	if (parentdn == 0) {
-		slapi_log_err(SLAPI_LOG_REPL, sessionid,
-				"tombstone_to_conflict_check_parent - no parent entry for: %s\n",
-				slapi_sdn_get_ndn(conflictdn));
-		return rc;
-	} else {
-		slapi_log_err(SLAPI_LOG_REPL, sessionid,
-				"tombstone_to_conflict_check_parent - checking parent entry: %s\n",
-				parentdn);
-	}
-	newpb = slapi_pblock_new();
-	slapi_search_internal_set_pb(
-					newpb,
-					parentdn,
-					LDAP_SCOPE_BASE,
-					"objectclass=*",
-					NULL, /*attrs*/
-					0, /*attrsonly*/
-					NULL, /*Controls*/
-					parentuniqueid, /*uniqueid*/
-					repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
-					0);
-	slapi_search_internal_pb(newpb); 
-	slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &op_result);
-	switch(op_result)
-	{
-	case LDAP_SUCCESS:
-		{
-		Slapi_Entry **entries= NULL;
-		slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
-		if(entries!=NULL && entries[0]!=NULL) {
-			if(is_conflict_entry(entries[0])) {
-				Slapi_DN *newsuperior = get_valid_parent_for_conflict(entries[0]);
-				Slapi_RDN *rdn = slapi_rdn_new();
-				slapi_sdn_get_rdn(conflictdn, rdn);
-				const char *newrdn = slapi_rdn_get_rdn(rdn);
-				op_result= urp_fixup_modrdn_entry(
-					conflictdn,
-					newrdn,
-					newsuperior,
-					uniqueid,
-					NULL,
-					NULL,
-					OP_FLAG_NOOP);
-				slapi_rdn_free(&rdn);
-				slapi_sdn_free(&newsuperior);
-			}
-		}
-		}
-		break;
-	default:
-		break;
-	}
+    int rc = 0;
+    int op_result;
+    Slapi_PBlock *newpb;
 
-	slapi_free_search_results_internal (newpb);
-	slapi_pblock_destroy(newpb);
-	return rc;
+    if (parentdn == 0) {
+        slapi_log_err(SLAPI_LOG_REPL, sessionid,
+                      "tombstone_to_conflict_check_parent - no parent entry for: %s\n",
+                      slapi_sdn_get_ndn(conflictdn));
+        return rc;
+    } else {
+        slapi_log_err(SLAPI_LOG_REPL, sessionid,
+                      "tombstone_to_conflict_check_parent - checking parent entry: %s\n",
+                      parentdn);
+    }
+    newpb = slapi_pblock_new();
+    slapi_search_internal_set_pb(
+        newpb,
+        parentdn,
+        LDAP_SCOPE_BASE,
+        "objectclass=*",
+        NULL,           /*attrs*/
+        0,              /*attrsonly*/
+        NULL,           /*Controls*/
+        parentuniqueid, /*uniqueid*/
+        repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+        0);
+    slapi_search_internal_pb(newpb);
+    slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &op_result);
+    switch (op_result) {
+    case LDAP_SUCCESS: {
+        Slapi_Entry **entries = NULL;
+        slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+        if (entries != NULL && entries[0] != NULL) {
+            if (is_conflict_entry(entries[0])) {
+                Slapi_DN *newsuperior = get_valid_parent_for_conflict(entries[0]);
+                Slapi_RDN *rdn = slapi_rdn_new();
+                slapi_sdn_get_rdn(conflictdn, rdn);
+                const char *newrdn = slapi_rdn_get_rdn(rdn);
+                op_result = urp_fixup_modrdn_entry(
+                    conflictdn,
+                    newrdn,
+                    newsuperior,
+                    uniqueid,
+                    NULL,
+                    NULL,
+                    OP_FLAG_NOOP);
+                slapi_rdn_free(&rdn);
+                slapi_sdn_free(&newsuperior);
+            }
+        }
+    } break;
+    default:
+        break;
+    }
+
+    slapi_free_search_results_internal(newpb);
+    slapi_pblock_destroy(newpb);
+    return rc;
 }
 
 static int
@@ -205,106 +202,108 @@ tombstone_to_glue_resolve_parent(
 int
 conflict_to_tombstone(char *sessionid, Slapi_Entry *entry, CSN *opcsn)
 {
-	int op_result = 0;
-	Slapi_RDN *srdn = slapi_rdn_new();
-	const char *uniqueid = slapi_entry_get_uniqueid ( entry );
-	const char *newrdn = NULL;
-	char *conflictdn = NULL;
-	char *replconflict = slapi_entry_attr_get_charptr(entry,ATTR_NSDS5_REPLCONFLICT );
-
-	if (replconflict) {
-		conflictdn = strstr(replconflict, " (ADD) ");
-		if (conflictdn == NULL) {
-			/* error, wrong type of conflict */
-			op_result = 1;
-		} else {
-			conflictdn += 7;
-			slapi_rdn_init_all_dn(srdn, conflictdn);
-			newrdn = slapi_rdn_get_nrdn(srdn);
-			slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
-				"conflict_to_tombstone - %s - valid entry dn: %s newrdn: %s\n",
-				sessionid, conflictdn, newrdn);
-		}
-	}
+    int op_result = 0;
+    Slapi_RDN *srdn = slapi_rdn_new();
+    const char *uniqueid = slapi_entry_get_uniqueid(entry);
+    const char *newrdn = NULL;
+    char *conflictdn = NULL;
+    char *replconflict = slapi_entry_attr_get_charptr(entry, ATTR_NSDS5_REPLCONFLICT);
+
+    if (replconflict) {
+        conflictdn = strstr(replconflict, " (ADD) ");
+        if (conflictdn == NULL) {
+            /* error, wrong type of conflict */
+            op_result = 1;
+        } else {
+            conflictdn += 7;
+            slapi_rdn_init_all_dn(srdn, conflictdn);
+            newrdn = slapi_rdn_get_nrdn(srdn);
+            slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+                          "conflict_to_tombstone - %s - valid entry dn: %s newrdn: %s\n",
+                          sessionid, conflictdn, newrdn);
+        }
+    }
 
-	if (op_result) goto done;
+    if (op_result)
+        goto done;
 
-	slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
-			"conflict_to_tombstone - %s - Renaming entry %s to %s\n",
-			sessionid, slapi_entry_get_dn_const (entry), newrdn);
-	op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP);
-	if (op_result) goto done;
+    slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+                  "conflict_to_tombstone - %s - Renaming entry %s to %s\n",
+                  sessionid, slapi_entry_get_dn_const(entry), newrdn);
+    op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP);
+    if (op_result)
+        goto done;
 
-	op_result = urp_fixup_delete_entry (uniqueid, slapi_entry_get_dn_const (entry), opcsn, 0);
+    op_result = urp_fixup_delete_entry(uniqueid, slapi_entry_get_dn_const(entry), opcsn, 0);
 
-done: 
-	slapi_ch_free_string(&replconflict);
-	slapi_rdn_free(&srdn);
-	return op_result;
+done:
+    slapi_ch_free_string(&replconflict);
+    slapi_rdn_free(&srdn);
+    return op_result;
 }
 
 /*
  * Convert a tombstone into a conflict entry.
  */
 int
-tombstone_to_conflict (
-	char *sessionid,
-	Slapi_Entry *tombstoneentry,
-	const Slapi_DN *conflictdn,
-	const char *reason,
-	CSN *opcsn,
-	Slapi_DN **newparentdn)
+tombstone_to_conflict(
+    char *sessionid,
+    Slapi_Entry *tombstoneentry,
+    const Slapi_DN *conflictdn,
+    const char *reason,
+    CSN *opcsn,
+    Slapi_DN **newparentdn)
 {
-	int op_result = 0;
-	Slapi_Mods smods;
-	char csnstr[CSN_STRSIZE+1];
-	char buf[BUFSIZ];
-	char *uniqueid = slapi_entry_attr_get_charptr(tombstoneentry, "nsuiqueid");
-	char *entrydn = slapi_entry_attr_get_charptr(tombstoneentry, "nscpentrydn");
-	char *parentuniqueid = slapi_entry_attr_get_charptr (tombstoneentry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID); /* Allocated */
-	char *parentdn = slapi_dn_parent(slapi_sdn_get_ndn(conflictdn));
-	const CSN *dncsn = entry_get_dncsn(tombstoneentry);
-	csn_as_string(dncsn, PR_FALSE, csnstr);
-
-	slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
-			                 "tombstone_to_conflict - %s - trying to resurrect tombstone as '%s'.\n",
-			                 sessionid, slapi_sdn_get_ndn(conflictdn));
-	slapi_sdn_set_normdn_byval(slapi_entry_get_sdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
-	/* not just e_sdn, e_rsdn needs to be updated. */
-	slapi_rdn_set_all_dn(slapi_entry_get_srdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
-	op_result = urp_fixup_add_entry (tombstoneentry, NULL, NULL, opcsn, OP_FLAG_RESURECT_ENTRY|OP_FLAG_NOOP);
-
-	if (op_result) {
-		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
-			"tombstone_to_conflict - %s - Can't resurrect tombstone, error=%d\n",
-			sessionid, op_result);
-		goto done;
-	}
+    int op_result = 0;
+    Slapi_Mods smods;
+    char csnstr[CSN_STRSIZE + 1];
+    char buf[BUFSIZ];
+    char *uniqueid = slapi_entry_attr_get_charptr(tombstoneentry, "nsuiqueid");
+    char *entrydn = slapi_entry_attr_get_charptr(tombstoneentry, "nscpentrydn");
+    char *parentuniqueid = slapi_entry_attr_get_charptr(tombstoneentry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID); /* Allocated */
+    char *parentdn = slapi_dn_parent(slapi_sdn_get_ndn(conflictdn));
+    const CSN *dncsn = entry_get_dncsn(tombstoneentry);
+    csn_as_string(dncsn, PR_FALSE, csnstr);
+
+    slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+                  "tombstone_to_conflict - %s - trying to resurrect tombstone as '%s'.\n",
+                  sessionid, slapi_sdn_get_ndn(conflictdn));
+    slapi_sdn_set_normdn_byval(slapi_entry_get_sdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
+    /* not just e_sdn, e_rsdn needs to be updated. */
+    slapi_rdn_set_all_dn(slapi_entry_get_srdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
+    op_result = urp_fixup_add_entry(tombstoneentry, NULL, NULL, opcsn, OP_FLAG_RESURECT_ENTRY | OP_FLAG_NOOP);
 
-	slapi_mods_init (&smods, 5);
-	slapi_mods_add (&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry");
-	slapi_mods_add (&smods, LDAP_MOD_DELETE, "objectclass", strlen("glue"),"glue");
-	slapi_mods_add (&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr), csnstr);
-	PR_snprintf (buf, sizeof(buf), "%s (%s) %s",
-	             REASON_ANNOTATE_DN, "ADD", entrydn);
-	slapi_mods_add (&smods, LDAP_MOD_ADD, ATTR_NSDS5_REPLCONFLICT, strlen(buf), buf);
-	op_result = urp_fixup_modify_entry (uniqueid, conflictdn, opcsn, &smods, 0);
-	slapi_mods_done (&smods);
-	if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
-		/* the objectclass was already present */
-		op_result = LDAP_SUCCESS;
-	}
-	/* this will go to postop 
+    if (op_result) {
+        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
+                      "tombstone_to_conflict - %s - Can't resurrect tombstone, error=%d\n",
+                      sessionid, op_result);
+        goto done;
+    }
+
+    slapi_mods_init(&smods, 5);
+    slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"), "ldapsubentry");
+    slapi_mods_add(&smods, LDAP_MOD_DELETE, "objectclass", strlen("glue"), "glue");
+    slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr), csnstr);
+    PR_snprintf(buf, sizeof(buf), "%s (%s) %s",
+                REASON_ANNOTATE_DN, "ADD", entrydn);
+    slapi_mods_add(&smods, LDAP_MOD_ADD, ATTR_NSDS5_REPLCONFLICT, strlen(buf), buf);
+    op_result = urp_fixup_modify_entry(uniqueid, conflictdn, opcsn, &smods, 0);
+    slapi_mods_done(&smods);
+    if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
+        /* the objectclass was already present */
+        op_result = LDAP_SUCCESS;
+    }
+/* this will go to postop
 	if (op_result == LDAP_SUCCESS) {
 		op_result = tombstone_to_conflict_check_parent(sessionid, parentdn, uniqueid, parentuniqueid, opcsn, conflictdn);
 	}
 	*/
 done:
-	slapi_ch_free_string(&uniqueid);
-	slapi_ch_free_string(&parentuniqueid);
-	slapi_ch_free_string(&parentdn);
-	slapi_ch_free_string(&entrydn);
-	return op_result;
+    slapi_ch_free_string(&uniqueid);
+    slapi_ch_free_string(&parentuniqueid);
+    slapi_ch_free_string(&parentdn);
+    slapi_ch_free_string(&entrydn);
+    return op_result;
 }
 
 /*


=====================================
ldap/servers/slapd/back-ldbm/monitor.c
=====================================
--- a/ldap/servers/slapd/back-ldbm/monitor.c
+++ b/ldap/servers/slapd/back-ldbm/monitor.c
@@ -157,7 +157,7 @@ ldbm_back_monitor_instance_search(Slapi_PBlock *pb __attribute__((unused)),
 #ifdef DEBUG
     {
         /* debugging for hash statistics */
-        char *x;
+        char *x = NULL;
         cache_debug_hash(&(inst->inst_cache), &x);
         val.bv_val = x;
         val.bv_len = strlen(x);


=====================================
ldap/servers/slapd/connection.c
=====================================
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -1716,7 +1716,9 @@ connection_threadmain()
         if ((tag != LDAP_REQ_UNBIND) && !thread_turbo_flag && !replication_connection) {
             if (!more_data) {
                 conn->c_flags &= ~CONN_FLAG_MAX_THREADS;
+                PR_EnterMonitor(conn->c_mutex);
                 connection_make_readable_nolock(conn);
+                PR_ExitMonitor(conn->c_mutex);
                 /* once the connection is readable, another thread may access conn,
                  * so need locking from here on */
                 signal_listner();
@@ -1822,9 +1824,17 @@ connection_threadmain()
 
             /* If we're in turbo mode, we keep our reference to the connection alive */
             /* can't use the more_data var because connection could have changed in another thread */
-            more_data = conn_buffered_data_avail_nolock(conn, &conn_closed) ? 1 : 0;
-            slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", "conn %" PRIu64 " check more_data %d thread_turbo_flag %d\n",
-                          conn->c_connid, more_data, thread_turbo_flag);
+            slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", "conn %" PRIu64 " check more_data %d thread_turbo_flag %d"
+                          "repl_conn_bef %d, repl_conn_now %d\n",
+                          conn->c_connid, more_data, thread_turbo_flag,
+                          replication_connection, conn->c_isreplication_session);
+            if (!replication_connection &&  conn->c_isreplication_session) {
+                /* it a connection that was just flagged as replication connection */
+                more_data = 0;
+            } else {
+                /* normal connection or already established replication connection */
+                more_data = conn_buffered_data_avail_nolock(conn, &conn_closed) ? 1 : 0;
+            }
             if (!more_data) {
                 if (!thread_turbo_flag) {
                     /*


=====================================
ldap/servers/slapd/csngen.c
=====================================
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -331,14 +331,18 @@ csngen_adjust_time(CSNGen *gen, const CSN *csn)
         /* let's revisit the seq num - if the new time is > the old
            tiem, we should reset the seq number to remote + 1 if
            this won't cause a wrap around */
-        if (new_time > cur_time) {
+        if (new_time >= cur_time) {
             /* just set seq_num regardless of whether the current one
                is < or > than the remote one - the goal of this function
                is to make sure we generate CSNs > the remote CSN - if
                we have increased the time, we can decrease the seqnum
                and still guarantee that any new CSNs generated will be
                > any current CSNs we have generated */
-            gen->state.seq_num = remote_seqnum + 1;
+            if (remote_seqnum < gen->state.seq_num) {
+                gen->state.seq_num ++;
+            } else {
+                gen->state.seq_num = remote_seqnum + 1;
+            }
         }
         if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
             slapi_log_err(SLAPI_LOG_REPL, "csngen_adjust_time",


=====================================
ldap/servers/slapd/daemon.c
=====================================
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -1087,12 +1087,18 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
         /* we have exited from ns_thrpool_wait. This means we are shutting down! */
         /* Please see https://firstyear.fedorapeople.org/nunc-stans/md_docs_job-safety.html */
         /* tldr is shutdown needs to run first to allow job_done on an ARMED job */
-        for (size_t i = 0; i < listeners; i++) {
-            PRStatus shutdown_status = ns_job_done(listener_idxs[i].ns_job);
-            if (shutdown_status != PR_SUCCESS) {
-                slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed to shutdown listener idx %" PRIu64 " !\n", i);
+        for (uint64_t i = 0; i < listeners; i++) {
+            PRStatus shutdown_status;
+
+            if (listener_idxs[i].ns_job) {
+                shutdown_status = ns_job_done(listener_idxs[i].ns_job);
+                if (shutdown_status != PR_SUCCESS) {
+                    slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed to shutdown listener idx %" PRIu64 " !\n", i);
+                }
+                PR_ASSERT(shutdown_status == PR_SUCCESS);
+            } else {
+                slapi_log_err(SLAPI_LOG_CRIT, "slapd_daemon", "Listeners uninitialized. Possibly the server was shutdown while starting\n");
             }
-            PR_ASSERT(shutdown_status == PR_SUCCESS);
             listener_idxs[i].ns_job = NULL;
         }
     } else {
@@ -1197,8 +1203,10 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
      * All the connection close jobs "should" complete before
      * shutdown at least.
      */
-    ns_thrpool_shutdown(tp);
-    ns_thrpool_wait(tp);
+    if (enable_nunc_stans) {
+        ns_thrpool_shutdown(tp);
+        ns_thrpool_wait(tp);
+    }
 
     threads = g_get_active_threadcnt();
     if (threads > 0) {
@@ -1676,22 +1684,25 @@ ns_handle_closure(struct ns_job_t *job)
 /**
  * Schedule more I/O for this connection, or make sure that it
  * is closed in the event loop.
+ * caller must hold c_mutex
+ * It returns
+ *  0 on success
+ *  1 on need to retry
  */
-void
-ns_connection_post_io_or_closing(Connection *conn)
+static int
+ns_connection_post_io_or_closing_try(Connection *conn)
 {
     struct timeval tv;
 
     if (!enable_nunc_stans) {
-        return;
+        return 0;
     }
 
     /*
      * Cancel any existing ns jobs we have registered.
      */
     if (conn->c_job != NULL) {
-        ns_job_done(conn->c_job);
-        conn->c_job = NULL;
+        return 1;
     }
 
     if (CONN_NEEDS_CLOSING(conn)) {
@@ -1701,7 +1712,7 @@ ns_connection_post_io_or_closing(Connection *conn)
             slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "Already a close "
                                                                                "job in progress on conn %" PRIu64 " for fd=%d\n",
                           conn->c_connid, conn->c_sd);
-            return;
+            return 0;
         } else {
             conn->c_ns_close_jobs++;                                                      /* now 1 active closure job */
             connection_acquire_nolock_ext(conn, 1 /* allow acquire even when closing */); /* event framework now has a reference */
@@ -1745,7 +1756,7 @@ ns_connection_post_io_or_closing(Connection *conn)
              * The error occurs when we get a connection in a closing state.
              * For now we return, but there is probably a better way to handle the error case.
              */
-            return;
+            return 0;
         }
 #endif
         ns_result_t job_result = ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
@@ -1767,6 +1778,28 @@ ns_connection_post_io_or_closing(Connection *conn)
                           conn->c_connid, conn->c_sd);
         }
     }
+    return 0;
+}
+void
+ns_connection_post_io_or_closing(Connection *conn)
+{
+    while (ns_connection_post_io_or_closing_try(conn)) {
+	/* we should retry later */
+	
+	/* We are not suppose to work immediately on the connection that is taken by
+	 * another job
+	 * release the lock and give some time
+	 */
+	
+	if (CONN_NEEDS_CLOSING(conn) && conn->c_ns_close_jobs) {
+	    return;
+	} else {
+	    PR_ExitMonitor(conn->c_mutex);
+	    DS_Sleep(PR_MillisecondsToInterval(100));
+
+	    PR_EnterMonitor(conn->c_mutex);
+	}
+    }
 }
 
 /* This function must be called without the thread flag, in the
@@ -2467,7 +2500,9 @@ ns_handle_new_connection(struct ns_job_t *job)
      * that poll() was avoided, even at the expense of putting this new fd back
      * in nunc-stans to poll for read ready.
      */
+    PR_EnterMonitor(c->c_mutex);
     ns_connection_post_io_or_closing(c);
+    PR_ExitMonitor(c->c_mutex);
     return;
 }
 


=====================================
ldap/servers/slapd/filter.c
=====================================
--- a/ldap/servers/slapd/filter.c
+++ b/ldap/servers/slapd/filter.c
@@ -472,7 +472,7 @@ get_substring_filter(
             f->f_sub_initial = val;
             eval = (char *)slapi_escape_filter_value(val, -1);
             if (eval) {
-                if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+                if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
                     fstr_len += (strlen(eval) + 1) * 2;
                     *fstr = slapi_ch_realloc(*fstr, fstr_len);
                 }
@@ -486,7 +486,7 @@ get_substring_filter(
             charray_add(&f->f_sub_any, val);
             eval = (char *)slapi_escape_filter_value(val, -1);
             if (eval) {
-                if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+                if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
                     fstr_len += (strlen(eval) + 1) * 2;
                     *fstr = slapi_ch_realloc(*fstr, fstr_len);
                 }
@@ -504,7 +504,7 @@ get_substring_filter(
             f->f_sub_final = val;
             eval = (char *)slapi_escape_filter_value(val, -1);
             if (eval) {
-                if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+                if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
                     fstr_len += (strlen(eval) + 1) * 2;
                     *fstr = slapi_ch_realloc(*fstr, fstr_len);
                 }
@@ -530,7 +530,7 @@ get_substring_filter(
     }
 
     filter_compute_hash(f);
-    if (fstr_len < strlen(*fstr) + 3) {
+    if (fstr_len <= strlen(*fstr) + 3) {
         fstr_len += 3;
         *fstr = slapi_ch_realloc(*fstr, fstr_len);
     }


=====================================
ldap/servers/slapd/slap.h
=====================================
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1650,7 +1650,7 @@ typedef struct conn
     void *c_io_layer_cb_data;            /* callback data */
     struct connection_table *c_ct;       /* connection table that this connection belongs to */
     ns_thrpool_t *c_tp;                  /* thread pool for this connection */
-    struct ns_job_t *c_job;                     /* If it exists, the current ns_job_t */
+    struct ns_job_t *c_job;              /* If it exists, the current ns_job_t */
     int c_ns_close_jobs;                 /* number of current close jobs */
     char *c_ipaddr;                      /* ip address str - used by monitor */
 } Connection;


=====================================
ldap/servers/slapd/util.c
=====================================
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -161,6 +161,11 @@ do_escape_string(
                     break;
                 }
                 do {
+                    if (bufSpace < 4) {
+                        memcpy(bufNext, "..", 2);
+                        bufNext += 2;
+                        goto bail;
+                    }
                     if (esc == UTIL_ESCAPE_BACKSLASH) {
                         /* *s is '\\' */
                         /* If *(s+1) and *(s+2) are both hex digits,
@@ -179,11 +184,6 @@ do_escape_string(
                             *bufNext++ = '\\';
                             --bufSpace;
                         }
-                        if (bufSpace < 3) {
-                            memcpy(bufNext, "..", 2);
-                            bufNext += 2;
-                            goto bail;
-                        }
                         PR_snprintf(bufNext, 3, "%02x", *(unsigned char *)s);
                         bufNext += 2;
                         bufSpace -= 2;



View it on GitLab: https://salsa.debian.org/freeipa-team/389-ds-base/compare/ce88dd0e9e2dc5eaa397221cf6140af4bd1bd03d...21800c3c1822e44c00304aa04eb4e04eaa55fc48

-- 
View it on GitLab: https://salsa.debian.org/freeipa-team/389-ds-base/compare/ce88dd0e9e2dc5eaa397221cf6140af4bd1bd03d...21800c3c1822e44c00304aa04eb4e04eaa55fc48
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-freeipa-devel/attachments/20180601/02604eda/attachment-0001.html>


More information about the Pkg-freeipa-devel mailing list