Blame SOURCES/0025-Ticket-48393-Improve-replication-config-validation.patch

081b2d
From c1ac23d7f5f6f14d75bd02cfd55818e2558f7cb9 Mon Sep 17 00:00:00 2001
081b2d
From: Mark Reynolds <mreynolds@redhat.com>
081b2d
Date: Fri, 3 Nov 2017 09:30:01 -0400
081b2d
Subject: [PATCH] Ticket 48393 - Improve replication config validation
081b2d
081b2d
Bug Description:  There was inconsistent behavior when modifying and adding replication
081b2d
                  configurations and agreements.  There were also a few places where
081b2d
                  unsigned ints were used for values which made checking for negative
081b2d
                  values impossible.
081b2d
081b2d
Fix Description:  Added a new function to properly check "number" attribute values.
081b2d
                  Also forced failure on the actual update if an invalid value was used
081b2d
                  (previously we would log an error and use some default value).  Also
081b2d
                  made all the int types consistent.
081b2d
081b2d
https://pagure.io/389-ds-base/issue/48393
081b2d
081b2d
Reviewed by: firstyear(Thanks!)
081b2d
081b2d
(cherry picked from commit f6b0e1841059460d6d0071cc771e3fbe834af393)
081b2d
---
081b2d
 .../suites/replication/replica_config_test.py      | 397 +++++++++++++++++++++
081b2d
 ldap/schema/01core389.ldif                         |   3 +-
081b2d
 ldap/servers/plugins/replication/repl5.h           |  54 +--
081b2d
 ldap/servers/plugins/replication/repl5_agmt.c      | 173 +++++----
081b2d
 ldap/servers/plugins/replication/repl5_replica.c   | 280 +++++++++------
081b2d
 .../plugins/replication/repl5_replica_config.c     | 158 ++++----
081b2d
 ldap/servers/plugins/replication/replutil.c        |  26 ++
081b2d
 7 files changed, 792 insertions(+), 299 deletions(-)
081b2d
 create mode 100644 dirsrvtests/tests/suites/replication/replica_config_test.py
081b2d
081b2d
diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py
081b2d
new file mode 100644
081b2d
index 000000000..50ea2ece9
081b2d
--- /dev/null
081b2d
+++ b/dirsrvtests/tests/suites/replication/replica_config_test.py
081b2d
@@ -0,0 +1,397 @@
081b2d
+import logging
081b2d
+import pytest
081b2d
+import copy
081b2d
+import os
081b2d
+import ldap
081b2d
+from lib389._constants import *
081b2d
+from lib389 import Entry
081b2d
+from lib389.topologies import topology_st as topo
081b2d
+
081b2d
+DEBUGGING = os.getenv("DEBUGGING", default=False)
081b2d
+if DEBUGGING:
081b2d
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
081b2d
+else:
081b2d
+    logging.getLogger(__name__).setLevel(logging.INFO)
081b2d
+log = logging.getLogger(__name__)
081b2d
+
081b2d
+REPLICA_DN = 'cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config'
081b2d
+AGMT_DN = 'cn=test_agreement,cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config'
081b2d
+notnum = 'invalid'
081b2d
+too_big = '9223372036854775807'
081b2d
+overflow = '9999999999999999999999999999999999999999999999999999999999999999999'
081b2d
+
081b2d
+replica_dict = {'objectclass': 'top nsDS5Replica'.split(),
081b2d
+                'nsDS5ReplicaRoot': 'dc=example,dc=com',
081b2d
+                'nsDS5ReplicaType': '3',
081b2d
+                'nsDS5Flags': '1',
081b2d
+                'nsDS5ReplicaId': '65535',
081b2d
+                'nsds5ReplicaPurgeDelay': '604800',
081b2d
+                'nsDS5ReplicaBindDN': 'cn=u',
081b2d
+                'cn': 'replica'}
081b2d
+
081b2d
+agmt_dict = {'objectClass': 'top nsDS5ReplicationAgreement'.split(),
081b2d
+             'cn': 'test_agreement',
081b2d
+             'nsDS5ReplicaRoot': 'dc=example,dc=com',
081b2d
+             'nsDS5ReplicaHost': 'localhost.localdomain',
081b2d
+             'nsDS5ReplicaPort': '5555',
081b2d
+             'nsDS5ReplicaBindDN': 'uid=tester',
081b2d
+             'nsds5ReplicaCredentials': 'password',
081b2d
+             'nsDS5ReplicaTransportInfo': 'LDAP',
081b2d
+             'nsDS5ReplicaBindMethod': 'SIMPLE'}
081b2d
+
081b2d
+
081b2d
+repl_add_attrs = [('nsDS5ReplicaType', '-1', '4', overflow, notnum, '1'),
081b2d
+                  ('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
081b2d
+                  ('nsDS5ReplicaId', '0', '65536', overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'),
081b2d
+                  ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')]
081b2d
+
081b2d
+repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'),
081b2d
+                  ('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'),
081b2d
+                  ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')]
081b2d
+
081b2d
+agmt_attrs = [('nsds5ReplicaPort', '0', '65536', overflow, notnum, '389'),
081b2d
+              ('nsds5ReplicaTimeout', '-1', too_big, overflow, notnum, '6'),
081b2d
+              ('nsds5ReplicaBusyWaitTime', '-1', too_big, overflow, notnum, '6'),
081b2d
+              ('nsds5ReplicaSessionPauseTime', '-1', too_big, overflow, notnum, '6'),
081b2d
+              ('nsds5ReplicaFlowControlWindow', '-1', too_big, overflow, notnum, '6'),
081b2d
+              ('nsds5ReplicaFlowControlPause', '-1', too_big, overflow, notnum, '6'),
081b2d
+              ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '6')]
081b2d
+
081b2d
+
081b2d
+def replica_setup(topo):
081b2d
+    """Add a valid replica config entry to modify
081b2d
+    """
081b2d
+    try:
081b2d
+        topo.standalone.delete_s(REPLICA_DN)
081b2d
+    except:
081b2d
+        pass
081b2d
+
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, replica_dict)))
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal("Failed to add replica entry: " + str(e))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+def replica_reset(topo):
081b2d
+    try:
081b2d
+        topo.standalone.delete_s(REPLICA_DN)
081b2d
+    except:
081b2d
+        pass
081b2d
+
081b2d
+
081b2d
+def agmt_setup(topo):
081b2d
+    """Add a valid replica config entry to modify
081b2d
+    """
081b2d
+    try:
081b2d
+        topo.standalone.delete_s(AGMT_DN)
081b2d
+    except:
081b2d
+        pass
081b2d
+
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, agmt_dict)))
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal("Failed to add agreement entry: " + str(e))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+def agmt_reset(topo):
081b2d
+    try:
081b2d
+        topo.standalone.delete_s(AGMT_DN)
081b2d
+    except:
081b2d
+        pass
081b2d
+
081b2d
+
081b2d
+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", repl_add_attrs)
081b2d
+def test_replica_num_add(topo, attr, too_small, too_big, overflow, notnum, valid):
081b2d
+    """Test all the number values you can set for a replica config entry
081b2d
+
081b2d
+    :id: a8b47d4a-a089-4d70-8070-e6181209bf92
081b2d
+    :setup: standalone instance
081b2d
+    :steps:
081b2d
+        1. Use a value that is too small
081b2d
+        2. Use a value that is too big
081b2d
+        3. Use a value that overflows the int
081b2d
+        4. Use a value with character value (not a number)
081b2d
+        5. Use a valid value
081b2d
+    :expectedresults:
081b2d
+        1. Add is rejected
081b2d
+        2. Add is rejected
081b2d
+        3. Add is rejected
081b2d
+        4. Add is rejected
081b2d
+        5. Add is allowed
081b2d
+    """
081b2d
+
081b2d
+    replica_reset(topo)
081b2d
+
081b2d
+    # Test too small
081b2d
+    my_replica = copy.deepcopy(replica_dict)
081b2d
+    my_replica[attr] = too_small
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, my_replica)))
081b2d
+        log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, too_small))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add replica entry with {}:{}  error: {}".format(attr, too_small, str(e)))
081b2d
+
081b2d
+    # Test too big
081b2d
+    my_replica = copy.deepcopy(replica_dict)
081b2d
+    my_replica[attr] = too_big
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, my_replica)))
081b2d
+        log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, too_big))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add replica entry with {}:{}  error: {}".format(attr, too_big, str(e)))
081b2d
+
081b2d
+    # Test overflow
081b2d
+    my_replica = copy.deepcopy(replica_dict)
081b2d
+    my_replica[attr] = overflow
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, my_replica)))
081b2d
+        log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, overflow))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add replica entry with {}:{}  error: {}".format(attr, overflow, str(e)))
081b2d
+
081b2d
+    # test not a number
081b2d
+    my_replica = copy.deepcopy(replica_dict)
081b2d
+    my_replica[attr] = notnum
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, my_replica)))
081b2d
+        log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, notnum))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add replica entry with {}:{}  error: {}".format(attr, notnum, str(e)))
081b2d
+
081b2d
+    # Test valid value
081b2d
+    my_replica = copy.deepcopy(replica_dict)
081b2d
+    my_replica[attr] = valid
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((REPLICA_DN, my_replica)))
081b2d
+        log.info("Correctly allowed to add replica entry with {}: {}".format(attr, valid))
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal("Incorrectly failed to add replica entry with {}: {}  error: {}".format(attr, valid, str(e)))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", repl_mod_attrs)
081b2d
+def test_replica_num_modify(topo, attr, too_small, too_big, overflow, notnum, valid):
081b2d
+    """Test all the number values you can set for a replica config entry
081b2d
+
081b2d
+    :id: a8b47d4a-a089-4d70-8070-e6181209bf93
081b2d
+    :setup: standalone instance
081b2d
+    :steps:
081b2d
+        1. Replace a value that is too small
081b2d
+        2. Repalce a value that is too big
081b2d
+        3. Replace a value that overflows the int
081b2d
+        4. Replace a value with character value (not a number)
081b2d
+        5. Replace a vlue with a valid value
081b2d
+    :expectedresults:
081b2d
+        1. Value is rejected
081b2d
+        2. Value is rejected
081b2d
+        3. Value is rejected
081b2d
+        4. Value is rejected
081b2d
+        5. Value is allowed
081b2d
+    """
081b2d
+
081b2d
+    # Value too small
081b2d
+    replica_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, too_small)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_small))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_small))
081b2d
+
081b2d
+    # Value too big
081b2d
+    replica_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, too_big)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_big))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_big))
081b2d
+
081b2d
+    # Value overflow
081b2d
+    replica_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, overflow)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, overflow))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, overflow))
081b2d
+
081b2d
+    # Value not a number
081b2d
+    replica_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, notnum)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, notnum))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, notnum))
081b2d
+
081b2d
+    # Value is valid
081b2d
+    replica_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, valid)])
081b2d
+        log.info('Correctly added valid agreement attribute value: {}:{}'.format(attr, valid))
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal('Valid value for {}:{} was incorrectly rejected.  Error {}'.format(attr, valid, str(e)))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", agmt_attrs)
081b2d
+def test_agmt_num_add(topo, attr, too_small, too_big, overflow, notnum, valid):
081b2d
+    """Test all the number values you can set for a replica config entry
081b2d
+
081b2d
+    :id: a8b47d4a-a089-4d70-8070-e6181209bf94
081b2d
+    :setup: standalone instance
081b2d
+    :steps:
081b2d
+        1. Use a value that is too small
081b2d
+        2. Use a value that is too big
081b2d
+        3. Use a value that overflows the int
081b2d
+        4. Use a value with character value (not a number)
081b2d
+        5. Use a valid value
081b2d
+    :expectedresults:
081b2d
+        1. Add is rejected
081b2d
+        2. Add is rejected
081b2d
+        3. Add is rejected
081b2d
+        4. Add is rejected
081b2d
+        5. Add is allowed
081b2d
+    """
081b2d
+    agmt_reset(topo)
081b2d
+
081b2d
+    # Test too small
081b2d
+    my_agmt = copy.deepcopy(agmt_dict)
081b2d
+    my_agmt[attr] = too_small
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, my_agmt)))
081b2d
+        log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, too_small))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add agreement entry with {}:{}  error: {}".format(attr, too_small, str(e)))
081b2d
+
081b2d
+    # Test too big
081b2d
+    my_agmt = copy.deepcopy(agmt_dict)
081b2d
+    my_agmt[attr] = too_big
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, my_agmt)))
081b2d
+        log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, too_big))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add agreement entry with {}:{}  error: {}".format(attr, too_big, str(e)))
081b2d
+
081b2d
+    # Test overflow
081b2d
+    my_agmt = copy.deepcopy(agmt_dict)
081b2d
+    my_agmt[attr] = overflow
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, my_agmt)))
081b2d
+        log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, overflow))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add agreement entry with {}:{}  error: {}".format(attr, overflow, str(e)))
081b2d
+
081b2d
+    # test not a number
081b2d
+    my_agmt = copy.deepcopy(agmt_dict)
081b2d
+    my_agmt[attr] = notnum
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, my_agmt)))
081b2d
+        log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, notnum))
081b2d
+        assert False
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.info("Correctly failed to add agreement entry with {}:{}  error: {}".format(attr, notnum, str(e)))
081b2d
+
081b2d
+    # Test valid value
081b2d
+    my_agmt = copy.deepcopy(agmt_dict)
081b2d
+    my_agmt[attr] = valid
081b2d
+    try:
081b2d
+        topo.standalone.add_s(Entry((AGMT_DN, my_agmt)))
081b2d
+        log.info("Correctly allowed to add agreement entry with {}: {}".format(attr, valid))
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal("Incorrectly failed to add agreement entry with {}: {}  error: {}".format(attr, valid, str(e)))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", agmt_attrs)
081b2d
+def test_agmt_num_modify(topo, attr, too_small, too_big, overflow, notnum, valid):
081b2d
+    """Test all the number values you can set for a replica config entry
081b2d
+
081b2d
+    :id: a8b47d4a-a089-4d70-8070-e6181209bf95
081b2d
+    :setup: standalone instance
081b2d
+    :steps:
081b2d
+        1. Replace a value that is too small
081b2d
+        2. Replace a value that is too big
081b2d
+        3. Replace a value that overflows the int
081b2d
+        4. Replace a value with character value (not a number)
081b2d
+        5. Replace a vlue with a valid value
081b2d
+    :expectedresults:
081b2d
+        1. Value is rejected
081b2d
+        2. Value is rejected
081b2d
+        3. Value is rejected
081b2d
+        4. Value is rejected
081b2d
+        5. Value is allowed
081b2d
+    """
081b2d
+
081b2d
+    # Value too small
081b2d
+    agmt_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, too_small)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_small))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_small))
081b2d
+
081b2d
+    # Value too big
081b2d
+    agmt_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, too_big)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_big))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_big))
081b2d
+
081b2d
+    # Value overflow
081b2d
+    agmt_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, overflow)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, overflow))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, overflow))
081b2d
+
081b2d
+    # Value not a number
081b2d
+    agmt_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, notnum)])
081b2d
+        log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, notnum))
081b2d
+        assert False
081b2d
+    except:
081b2d
+        log.info('Invalid value for {}:{} was correctly rejected'.format(attr, notnum))
081b2d
+
081b2d
+    # Value is valid
081b2d
+    agmt_setup(topo)
081b2d
+    try:
081b2d
+        topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, valid)])
081b2d
+    except ldap.LDAPError as e:
081b2d
+        log.fatal('Valid value for {}:{} was incorrectly rejected.  Error {}'.format(attr, valid, str(e)))
081b2d
+        assert False
081b2d
+
081b2d
+
081b2d
+if __name__ == '__main__':
081b2d
+    # Run isolated
081b2d
+    # -s for DEBUG mode
081b2d
+    CURRENT_FILE = os.path.realpath(__file__)
081b2d
+    pytest.main("-s %s" % CURRENT_FILE)
081b2d
+
081b2d
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
081b2d
index 246495214..ab124c86c 100644
081b2d
--- a/ldap/schema/01core389.ldif
081b2d
+++ b/ldap/schema/01core389.ldif
081b2d
@@ -303,6 +303,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2331 NAME 'nsslapd-logging-hr-timestamps
081b2d
 attributeTypes: ( 2.16.840.1.113730.3.1.2332 NAME 'allowWeakDHParam' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
081b2d
 attributeTypes: ( 2.16.840.1.113730.3.1.2333 NAME 'nsds5ReplicaReleaseTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
081b2d
 attributeTypes: ( 2.16.840.1.113730.3.1.2335 NAME 'nsds5ReplicaIgnoreMissingChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
081b2d
+attributeTypes: ( 2.16.840.1.113730.3.1.2336 NAME 'nsDS5ReplicaBindDnGroupCheckInterval' DESC 'Replication configuration setting for controlling the bind dn group check interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
081b2d
 #
081b2d
 # objectclasses
081b2d
 #
081b2d
@@ -312,7 +313,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.44 NAME 'nsIndex' DESC 'Netscape defined
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.109 NAME 'nsBackendInstance' DESC 'Netscape defined objectclass' SUP top  MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape defined objectclass' SUP top  MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top  MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
081b2d
-objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top  MUST ( nsDS5ReplicaRoot $  nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout ) X-ORIGIN 'Netscape Directory Server' )
081b2d
+objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Replication configuration objectclass' SUP top  MUST ( nsDS5ReplicaRoot $  nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout $ nsDS5ReplicaBindDnGroupCheckInterval ) X-ORIGIN 'Netscape Directory Server' )
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nstombstonecsn $ nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' )
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaFlowControlWindow $ nsds5ReplicaFlowControlPause $ nsDS5ReplicaWaitForAsyncResults $ nsds5ReplicaIgnoreMissingChange) X-ORIGIN 'Netscape Directory Server' )
081b2d
 objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' )
081b2d
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
081b2d
index 3bd878d4d..c6e79b7e2 100644
081b2d
--- a/ldap/servers/plugins/replication/repl5.h
081b2d
+++ b/ldap/servers/plugins/replication/repl5.h
081b2d
@@ -330,8 +330,8 @@ void replsupplier_configure(Repl_Supplier *rs, Slapi_PBlock *pb);
081b2d
 void replsupplier_start(Repl_Supplier *rs);
081b2d
 void replsupplier_stop(Repl_Supplier *rs);
081b2d
 void replsupplier_destroy(Repl_Supplier **rs);
081b2d
-void replsupplier_notify(Repl_Supplier *rs, PRUint32 eventmask);
081b2d
-PRUint32 replsupplier_get_status(Repl_Supplier *rs);
081b2d
+void replsupplier_notify(Repl_Supplier *rs, uint32_t eventmask);
081b2d
+uint32_t replsupplier_get_status(Repl_Supplier *rs);
081b2d
 
081b2d
 /* In repl5_plugins.c */
081b2d
 int multimaster_set_local_purl(void);
081b2d
@@ -383,7 +383,7 @@ int agmt_stop(Repl_Agmt *ra);
081b2d
 int agmt_replicate_now(Repl_Agmt *ra);
081b2d
 char *agmt_get_hostname(const Repl_Agmt *ra);
081b2d
 int agmt_get_port(const Repl_Agmt *ra);
081b2d
-PRUint32 agmt_get_transport_flags(const Repl_Agmt *ra);
081b2d
+uint32_t agmt_get_transport_flags(const Repl_Agmt *ra);
081b2d
 char *agmt_get_binddn(const Repl_Agmt *ra);
081b2d
 struct berval *agmt_get_credentials(const Repl_Agmt *ra);
081b2d
 int agmt_get_bindmethod(const Repl_Agmt *ra);
081b2d
@@ -448,8 +448,8 @@ int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e);
081b2d
 int agmt_set_timeout(Repl_Agmt *ra, long timeout);
081b2d
 int agmt_set_ignoremissing(Repl_Agmt *ra, long ignoremissing);
081b2d
 void agmt_update_done(Repl_Agmt *ra, int is_total);
081b2d
-PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt);
081b2d
-void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout);
081b2d
+uint64_t agmt_get_protocol_timeout(Repl_Agmt *agmt);
081b2d
+void agmt_set_protocol_timeout(Repl_Agmt *agmt, uint64_t timeout);
081b2d
 void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn);
081b2d
 void add_agmt_maxcsns(Slapi_Entry *e, Replica *r);
081b2d
 void agmt_remove_maxcsn(Repl_Agmt *ra);
081b2d
@@ -532,8 +532,8 @@ void *consumer_connection_extension_constructor(void *object, void *parent);
081b2d
 void consumer_connection_extension_destructor(void *ext, void *object, void *parent);
081b2d
 
081b2d
 /* extension helpers for managing exclusive access */
081b2d
-consumer_connection_extension *consumer_connection_extension_acquire_exclusive_access(void *conn, PRUint64 connid, int opid);
081b2d
-int consumer_connection_extension_relinquish_exclusive_access(void *conn, PRUint64 connid, int opid, PRBool force);
081b2d
+consumer_connection_extension *consumer_connection_extension_acquire_exclusive_access(void *conn, uint64_t connid, int opid);
081b2d
+int consumer_connection_extension_relinquish_exclusive_access(void *conn, uint64_t connid, int opid, PRBool force);
081b2d
 
081b2d
 /* mapping tree extension - stores replica object */
081b2d
 typedef struct multimaster_mtnode_extension
081b2d
@@ -666,8 +666,8 @@ Replica *replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_o
081b2d
 void replica_destroy(void **arg);
081b2d
 int replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid);
081b2d
 int replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid);
081b2d
-PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opid, const char *locking_purl, char **current_purl);
081b2d
-void replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid);
081b2d
+PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, uint64_t connid, int opid, const char *locking_purl, char **current_purl);
081b2d
+void replica_relinquish_exclusive_access(Replica *r, uint64_t connid, int opid);
081b2d
 PRBool replica_get_tombstone_reap_active(const Replica *r);
081b2d
 const Slapi_DN *replica_get_root(const Replica *r);
081b2d
 const char *replica_get_name(const Replica *r);
081b2d
@@ -685,11 +685,13 @@ PRBool replica_is_updatedn(Replica *r, const Slapi_DN *sdn);
081b2d
 void replica_set_updatedn(Replica *r, const Slapi_ValueSet *vs, int mod_op);
081b2d
 void replica_set_groupdn(Replica *r, const Slapi_ValueSet *vs, int mod_op);
081b2d
 char *replica_get_generation(const Replica *r);
081b2d
+
081b2d
 /* currently supported flags */
081b2d
 #define REPLICA_LOG_CHANGES 0x1 /* enable change logging */
081b2d
-PRBool replica_is_flag_set(const Replica *r, PRUint32 flag);
081b2d
-void replica_set_flag(Replica *r, PRUint32 flag, PRBool clear);
081b2d
-void replica_replace_flags(Replica *r, PRUint32 flags);
081b2d
+
081b2d
+PRBool replica_is_flag_set(const Replica *r, uint32_t flag);
081b2d
+void replica_set_flag(Replica *r, uint32_t flag, PRBool clear);
081b2d
+void replica_replace_flags(Replica *r, uint32_t flags);
081b2d
 void replica_dump(Replica *r);
081b2d
 void replica_set_enabled(Replica *r, PRBool enable);
081b2d
 Object *replica_get_replica_from_dn(const Slapi_DN *dn);
081b2d
@@ -720,7 +722,7 @@ int replica_delete_by_dn(const char *dn);
081b2d
 int replica_is_being_configured(const char *dn);
081b2d
 void consumer5_set_mapping_tree_state_for_replica(const Replica *r, RUV *supplierRuv);
081b2d
 Object *replica_get_for_backend(const char *be_name);
081b2d
-void replica_set_purge_delay(Replica *r, PRUint32 purge_delay);
081b2d
+void replica_set_purge_delay(Replica *r, uint32_t purge_delay);
081b2d
 void replica_set_tombstone_reap_interval(Replica *r, long interval);
081b2d
 void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv);
081b2d
 void replica_set_ruv_dirty(Replica *r);
081b2d
@@ -730,20 +732,20 @@ char *replica_get_dn(Replica *r);
081b2d
 void replica_check_for_tasks(Replica *r, Slapi_Entry *e);
081b2d
 void replica_update_state(time_t when, void *arg);
081b2d
 void replica_reset_csn_pl(Replica *r);
081b2d
-PRUint64 replica_get_protocol_timeout(Replica *r);
081b2d
-void replica_set_protocol_timeout(Replica *r, PRUint64 timeout);
081b2d
-PRUint64 replica_get_release_timeout(Replica *r);
081b2d
-void replica_set_release_timeout(Replica *r, PRUint64 timeout);
081b2d
+uint64_t replica_get_protocol_timeout(Replica *r);
081b2d
+void replica_set_protocol_timeout(Replica *r, uint64_t timeout);
081b2d
+uint64_t replica_get_release_timeout(Replica *r);
081b2d
+void replica_set_release_timeout(Replica *r, uint64_t timeout);
081b2d
 void replica_set_groupdn_checkinterval(Replica *r, int timeout);
081b2d
-PRUint64 replica_get_backoff_min(Replica *r);
081b2d
-PRUint64 replica_get_backoff_max(Replica *r);
081b2d
-void replica_set_backoff_min(Replica *r, PRUint64 min);
081b2d
-void replica_set_backoff_max(Replica *r, PRUint64 max);
081b2d
+uint64_t replica_get_backoff_min(Replica *r);
081b2d
+uint64_t replica_get_backoff_max(Replica *r);
081b2d
+void replica_set_backoff_min(Replica *r, uint64_t min);
081b2d
+void replica_set_backoff_max(Replica *r, uint64_t max);
081b2d
 int replica_get_agmt_count(Replica *r);
081b2d
 void replica_incr_agmt_count(Replica *r);
081b2d
 void replica_decr_agmt_count(Replica *r);
081b2d
-PRUint64 replica_get_precise_purging(Replica *r);
081b2d
-void replica_set_precise_purging(Replica *r, PRUint64 on_off);
081b2d
+uint64_t replica_get_precise_purging(Replica *r);
081b2d
+void replica_set_precise_purging(Replica *r, uint64_t on_off);
081b2d
 PRBool ignore_error_and_keep_going(int error);
081b2d
 void replica_check_release_timeout(Replica *r, Slapi_PBlock *pb);
081b2d
 void replica_lock_replica(Replica *r);
081b2d
@@ -764,8 +766,8 @@ void replica_unlock_replica(Replica *r);
081b2d
                                               is active, RECV should back off. And vice versa.  But SEND can coexist. */
081b2d
 #define REPLICA_TOTAL_EXCL_RECV         32 /* ditto */
081b2d
 
081b2d
-PRBool replica_is_state_flag_set(Replica *r, PRInt32 flag);
081b2d
-void replica_set_state_flag(Replica *r, PRUint32 flag, PRBool clear);
081b2d
+PRBool replica_is_state_flag_set(Replica *r, int32_t flag);
081b2d
+void replica_set_state_flag(Replica *r, uint32_t flag, PRBool clear);
081b2d
 void replica_set_tombstone_reap_stop(Replica *r, PRBool val);
081b2d
 void replica_enable_replication(Replica *r);
081b2d
 void replica_disable_replication(Replica *r, Object *r_obj);
081b2d
@@ -836,6 +838,8 @@ LDAPControl *create_managedsait_control(void);
081b2d
 LDAPControl *create_backend_control(Slapi_DN *sdn);
081b2d
 void repl_set_mtn_state_and_referrals(const Slapi_DN *sdn, const char *mtn_state, const RUV *ruv, char **ruv_referrals, char **other_referrals);
081b2d
 void repl_set_repl_plugin_path(const char *path);
081b2d
+int repl_config_valid_num(const char *config_attr, char *config_attr_value, int64_t min, int64_t max,
081b2d
+                          int *returncode, char *errortext, int64_t *retval);
081b2d
 
081b2d
 /* repl5_updatedn_list.c */
081b2d
 typedef void *ReplicaUpdateDNList;
081b2d
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
081b2d
index e2ab320e4..78fb91ae6 100644
081b2d
--- a/ldap/servers/plugins/replication/repl5_agmt.c
081b2d
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
081b2d
@@ -65,31 +65,31 @@
081b2d
 struct changecounter
081b2d
 {
081b2d
     ReplicaId rid;
081b2d
-    PRUint32 num_replayed;
081b2d
-    PRUint32 num_skipped;
081b2d
+    uint32_t num_replayed;
081b2d
+    uint32_t num_skipped;
081b2d
 };
081b2d
 
081b2d
 typedef struct repl5agmt
081b2d
 {
081b2d
     char *hostname;                        /* remote hostname */
081b2d
-    int port;                              /* port of remote server */
081b2d
-    PRUint32 transport_flags;              /* SSL, TLS, etc. */
081b2d
+    int64_t port;                          /* port of remote server */
081b2d
+    uint32_t transport_flags;              /* SSL, TLS, etc. */
081b2d
     char *binddn;                          /* DN to bind as */
081b2d
     struct berval *creds;                  /* Password, or certificate */
081b2d
-    int bindmethod;                        /* Bind method - simple, SSL */
081b2d
+    int64_t bindmethod;                    /* Bind method - simple, SSL */
081b2d
     Slapi_DN *replarea;                    /* DN of replicated area */
081b2d
     char **frac_attrs;                     /* list of fractional attributes to be replicated */
081b2d
     char **frac_attrs_total;               /* list of fractional attributes to be replicated for total update protocol */
081b2d
     PRBool frac_attr_total_defined;        /* TRUE if frac_attrs_total is defined */
081b2d
     Schedule *schedule;                    /* Scheduling information */
081b2d
-    int auto_initialize;                   /* 1 = automatically re-initialize replica */
081b2d
+    int64_t auto_initialize;               /* 1 = automatically re-initialize replica */
081b2d
     const Slapi_DN *dn;                    /* DN of replication agreement entry */
081b2d
     const Slapi_RDN *rdn;                  /* RDN of replication agreement entry */
081b2d
     char *long_name;                       /* Long name (rdn + host, port) of entry, for logging */
081b2d
     Repl_Protocol *protocol;               /* Protocol object - manages protocol */
081b2d
     struct changecounter **changecounters; /* changes sent/skipped since server start up */
081b2d
-    int num_changecounters;
081b2d
-    int max_changecounters;
081b2d
+    int64_t num_changecounters;
081b2d
+    int64_t max_changecounters;
081b2d
     time_t last_update_start_time;       /* Local start time of last update session */
081b2d
     time_t last_update_end_time;         /* Local end time of last update session */
081b2d
     char last_update_status[STATUS_LEN]; /* Status of last update. Format = numeric code <space> textual description */
081b2d
@@ -102,35 +102,35 @@ typedef struct repl5agmt
081b2d
     Object *consumerRUV;     /* last RUV received from the consumer - used for changelog purging */
081b2d
     CSN *consumerSchemaCSN;  /* last schema CSN received from the consumer */
081b2d
     ReplicaId consumerRID;   /* indicates if the consumer is the originator of a CSN */
081b2d
-    int tmpConsumerRID;      /* Indicates the consumer rid was set from the agmt maxcsn - it should be refreshed */
081b2d
-    long timeout;            /* timeout (in seconds) for outbound LDAP connections to remote server */
081b2d
+    int64_t tmpConsumerRID;  /* Indicates the consumer rid was set from the agmt maxcsn - it should be refreshed */
081b2d
+    int64_t timeout;         /* timeout (in seconds) for outbound LDAP connections to remote server */
081b2d
     PRBool stop_in_progress; /* set by agmt_stop when shutting down */
081b2d
-    long busywaittime;       /* time in seconds to wait after getting a REPLICA BUSY from the consumer -
081b2d
-                          to allow another supplier to finish sending its updates -
081b2d
-                          if set to 0, this means to use the default value if we get a busy
081b2d
-                          signal from the consumer */
081b2d
-    long pausetime;          /* time in seconds to pause after sending updates -
081b2d
-                       to allow another supplier to send its updates -
081b2d
-                       should be greater than busywaittime -
081b2d
-                       if set to 0, this means do not pause */
081b2d
+    int64_t busywaittime;    /* time in seconds to wait after getting a REPLICA BUSY from the consumer -
081b2d
+                              * to allow another supplier to finish sending its updates -
081b2d
+                              * if set to 0, this means to use the default value if we get a busy
081b2d
+                              * signal from the consumer
081b2d
+                              */
081b2d
+    int64_t pausetime;       /* time in seconds to pause after sending updates -
081b2d
+                              * to allow another supplier to send its updates -
081b2d
+                              * should be greater than busywaittime -
081b2d
+                              * if set to 0, this means do not pause
081b2d
+                              */
081b2d
     void *priv;              /* private data, used for windows-specific agreement data
081b2d
-                   for sync agreements or for replication session plug-in
081b2d
-                   private data for normal replication agreements */
081b2d
+                              * for sync agreements or for replication session plug-in
081b2d
+                              * private data for normal replication agreements
081b2d
+                              */
081b2d
     char **attrs_to_strip;   /* for fractional replication, if a "mod" is empty, strip out these attributes:
081b2d
-                            * modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
081b2d
-    int agreement_type;
081b2d
+                              * modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
081b2d
+    int64_t agreement_type;
081b2d
     Slapi_Counter *protocol_timeout;
081b2d
-    char *maxcsn;             /* agmt max csn */
081b2d
-    long flowControlWindow;   /* This is the maximum number of entries
081b2d
-                             * sent without acknowledgment
081b2d
-                             */
081b2d
-    long flowControlPause;    /* When nb of not acknowledged entries overpass totalUpdateWindow
081b2d
-                            * This is the duration (in msec) that the RA will pause before sending the next entry
081b2d
-                            */
081b2d
-    long ignoreMissingChange; /* if set replication will try to continue even if change cannot be found in changelog */
081b2d
-    Slapi_RWLock *attr_lock;  /* RW lock for all the stripped attrs */
081b2d
-    int WaitForAsyncResults;  /* Pass to DS_Sleep(PR_MillisecondsToInterval(WaitForAsyncResults))
081b2d
-                              * in repl5_inc_waitfor_async_results */
081b2d
+    char *maxcsn;                /* agmt max csn */
081b2d
+    int64_t flowControlWindow;   /* This is the maximum number of entries sent without acknowledgment */
081b2d
+    int64_t flowControlPause;    /* When nb of not acknowledged entries overpass totalUpdateWindow
081b2d
+                                  * This is the duration (in msec) that the RA will pause before sending the next entry */
081b2d
+    int64_t ignoreMissingChange; /* if set replication will try to continue even if change cannot be found in changelog */
081b2d
+    Slapi_RWLock *attr_lock;     /* RW lock for all the stripped attrs */
081b2d
+    int64_t WaitForAsyncResults; /* Pass to DS_Sleep(PR_MillisecondsToInterval(WaitForAsyncResults))
081b2d
+                                  * in repl5_inc_waitfor_async_results */
081b2d
 } repl5agmt;
081b2d
 
081b2d
 /* Forward declarations */
081b2d
@@ -182,7 +182,7 @@ agmt_is_valid(Repl_Agmt *ra)
081b2d
     }
081b2d
     if (ra->port <= 0) {
081b2d
         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "agmt_is_valid - Replication agreement \"%s\" "
081b2d
-                                                       "is malformed: invalid port number %d.\n",
081b2d
+                                                       "is malformed: invalid port number %ld.\n",
081b2d
                       slapi_sdn_get_dn(ra->dn), ra->port);
081b2d
         return_value = 0;
081b2d
     }
081b2d
@@ -241,10 +241,14 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
 {
081b2d
     Repl_Agmt *ra;
081b2d
     Slapi_Attr *sattr;
081b2d
+    char errormsg[SLAPI_DSE_RETURNTEXT_SIZE];
081b2d
     char *tmpstr;
081b2d
     char **denied_attrs = NULL;
081b2d
     char *auto_initialize = NULL;
081b2d
     char *val_nsds5BeginReplicaRefresh = "start";
081b2d
+    char *val = NULL;
081b2d
+    int64_t ptimeout = 0;
081b2d
+    int rc = 0;
081b2d
 
081b2d
     ra = (Repl_Agmt *)slapi_ch_calloc(1, sizeof(repl5agmt));
081b2d
     if ((ra->lock = PR_NewLock()) == NULL) {
081b2d
@@ -283,8 +287,17 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
 
081b2d
     /* Host name of remote replica */
081b2d
     ra->hostname = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaHost);
081b2d
+
081b2d
     /* Port number for remote replica instance */
081b2d
-    ra->port = slapi_entry_attr_get_int(e, type_nsds5ReplicaPort);
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaPort))){
081b2d
+        int64_t port;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaPort, val, 1, 65535, &rc, errormsg, &port) != 0) {
081b2d
+            goto loser;
081b2d
+        }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->port = port;
081b2d
+    }
081b2d
+
081b2d
     /* SSL, TLS, or other transport stuff */
081b2d
     ra->transport_flags = 0;
081b2d
     (void)agmt_set_transportinfo_no_lock(ra, e);
081b2d
@@ -313,29 +326,35 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
 
081b2d
     /* timeout. */
081b2d
     ra->timeout = DEFAULT_TIMEOUT;
081b2d
-    if (slapi_entry_attr_find(e, type_nsds5ReplicaTimeout, &sattr) == 0) {
081b2d
-        Slapi_Value *sval;
081b2d
-        if (slapi_attr_first_value(sattr, &sval) == 0) {
081b2d
-            ra->timeout = slapi_value_get_long(sval);
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaTimeout))){
081b2d
+        int64_t timeout;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &timeout) != 0) {
081b2d
+            goto loser;
081b2d
         }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->timeout = timeout;
081b2d
     }
081b2d
 
081b2d
     /* flow control update window. */
081b2d
     ra->flowControlWindow = DEFAULT_FLOWCONTROL_WINDOW;
081b2d
-    if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlWindow, &sattr) == 0) {
081b2d
-        Slapi_Value *sval;
081b2d
-        if (slapi_attr_first_value(sattr, &sval) == 0) {
081b2d
-            ra->flowControlWindow = slapi_value_get_long(sval);
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlWindow))){
081b2d
+        int64_t flow;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) {
081b2d
+            goto loser;
081b2d
         }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->flowControlWindow = flow;
081b2d
     }
081b2d
 
081b2d
     /* flow control update pause. */
081b2d
     ra->flowControlPause = DEFAULT_FLOWCONTROL_PAUSE;
081b2d
-    if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlPause, &sattr) == 0) {
081b2d
-        Slapi_Value *sval;
081b2d
-        if (slapi_attr_first_value(sattr, &sval) == 0) {
081b2d
-            ra->flowControlPause = slapi_value_get_long(sval);
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlPause))){
081b2d
+        int64_t pause;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaFlowControlPause, val, 0, INT_MAX, &rc, errormsg, &pause) != 0) {
081b2d
+            goto loser;
081b2d
         }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->flowControlPause = pause;
081b2d
     }
081b2d
 
081b2d
     /* continue on missing change ? */
081b2d
@@ -357,7 +376,6 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
     if (NULL != tmpstr) {
081b2d
         Object *repl_obj;
081b2d
         Replica *replica;
081b2d
-        PRUint64 ptimeout = 0;
081b2d
 
081b2d
         ra->replarea = slapi_sdn_new_dn_passin(tmpstr);
081b2d
 
081b2d
@@ -367,14 +385,18 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
                 replica_incr_agmt_count(replica);
081b2d
             }
081b2d
         }
081b2d
+    }
081b2d
 
081b2d
-        /* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
081b2d
-        ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
081b2d
-        if (ptimeout) {
081b2d
-            slapi_counter_set_value(ra->protocol_timeout, ptimeout);
081b2d
+    /* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_replicaProtocolTimeout))){
081b2d
+        if (repl_config_valid_num(type_replicaProtocolTimeout, val, 0, INT_MAX, &rc, errormsg, &ptimeout) != 0) {
081b2d
+            goto loser;
081b2d
         }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        slapi_counter_set_value(ra->protocol_timeout, ptimeout);
081b2d
     }
081b2d
 
081b2d
+
081b2d
     /* Replica enabled */
081b2d
     tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaEnabled);
081b2d
     if (NULL != tmpstr) {
081b2d
@@ -384,9 +406,8 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
             ra->is_enabled = PR_TRUE;
081b2d
         } else {
081b2d
             slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "agmt_new_from_entry - "
081b2d
-                                                           "Warning invalid value for nsds5ReplicaEnabled (%s), value must be \"on\" or \"off\".  "
081b2d
-                                                           "Ignoring this repl agreement.\n",
081b2d
-                          tmpstr);
081b2d
+                    "Warning invalid value for nsds5ReplicaEnabled (%s), value must be \"on\" or \"off\".  "
081b2d
+                    "Ignoring this repl agreement.\n", tmpstr);
081b2d
             slapi_ch_free_string(&tmpstr);
081b2d
             goto loser;
081b2d
         }
081b2d
@@ -402,11 +423,24 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
     }
081b2d
 
081b2d
     /* busy wait time - time to wait after getting REPLICA BUSY from consumer */
081b2d
-    ra->busywaittime = slapi_entry_attr_get_long(e, type_nsds5ReplicaBusyWaitTime);
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaBusyWaitTime))){
081b2d
+        int64_t busytime = 0;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaBusyWaitTime, val, 0, INT_MAX, &rc, errormsg, &busytime) != 0) {
081b2d
+            goto loser;
081b2d
+        }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->busywaittime = busytime;
081b2d
+    }
081b2d
 
081b2d
     /* pause time - time to pause after a session has ended */
081b2d
-    ra->pausetime = slapi_entry_attr_get_long(e, type_nsds5ReplicaSessionPauseTime);
081b2d
-
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaSessionPauseTime))){
081b2d
+        int64_t pausetime = 0;
081b2d
+        if (repl_config_valid_num(type_nsds5ReplicaSessionPauseTime, val, 0, INT_MAX, &rc, errormsg, &pausetime) != 0) {
081b2d
+            goto loser;
081b2d
+        }
081b2d
+        slapi_ch_free_string(&val;;
081b2d
+        ra->pausetime = pausetime;
081b2d
+    }
081b2d
     /* consumer's RUV */
081b2d
     if (slapi_entry_attr_find(e, type_ruvElement, &sattr) == 0) {
081b2d
         RUV *ruv;
081b2d
@@ -434,7 +468,7 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
         if (dot) {
081b2d
             *dot = '\0';
081b2d
         }
081b2d
-        ra->long_name = slapi_ch_smprintf("agmt=\"%s\" (%s:%d)", agmtname, hostname, ra->port);
081b2d
+        ra->long_name = slapi_ch_smprintf("agmt=\"%s\" (%s:%ld)", agmtname, hostname, ra->port);
081b2d
     }
081b2d
 
081b2d
     /* DBDB: review this code */
081b2d
@@ -534,6 +568,9 @@ agmt_new_from_entry(Slapi_Entry *e)
081b2d
 
081b2d
     return ra;
081b2d
 loser:
081b2d
+    slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
081b2d
+                  "agmt_new_from_entry - Failed to parse agreement, skipping.\n");
081b2d
+    slapi_ch_free_string(&val;;
081b2d
     agmt_delete((void **)&ra);
081b2d
     return NULL;
081b2d
 }
081b2d
@@ -754,10 +791,10 @@ agmt_start(Repl_Agmt *ra)
081b2d
                     char buf[BUFSIZ];
081b2d
                     char unavail_buf[BUFSIZ];
081b2d
 
081b2d
-                    PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%d;", slapi_sdn_get_dn(repl_sdn),
081b2d
+                    PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%ld;", slapi_sdn_get_dn(repl_sdn),
081b2d
                                 slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)),
081b2d
                                 ra->hostname, ra->port);
081b2d
-                    PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(repl_sdn),
081b2d
+                    PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%ld;unavailable", slapi_sdn_get_dn(repl_sdn),
081b2d
                                 slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)),
081b2d
                                 ra->hostname, ra->port);
081b2d
                     if (strstr(maxcsns[i], buf) || strstr(maxcsns[i], unavail_buf)) {
081b2d
@@ -901,7 +938,7 @@ agmt_get_port(const Repl_Agmt *ra)
081b2d
 /*
081b2d
  * Return the transport flags for this agreement.
081b2d
  */
081b2d
-PRUint32
081b2d
+uint32_t
081b2d
 agmt_get_transport_flags(const Repl_Agmt *ra)
081b2d
 {
081b2d
     unsigned int return_value;
081b2d
@@ -2919,7 +2956,7 @@ agmt_update_done(Repl_Agmt *agmt, int is_total)
081b2d
     }
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 agmt_get_protocol_timeout(Repl_Agmt *agmt)
081b2d
 {
081b2d
     if (agmt) {
081b2d
@@ -2930,7 +2967,7 @@ agmt_get_protocol_timeout(Repl_Agmt *agmt)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout)
081b2d
+agmt_set_protocol_timeout(Repl_Agmt *agmt, uint64_t timeout)
081b2d
 {
081b2d
     if (agmt) {
081b2d
         slapi_counter_set_value(agmt->protocol_timeout, timeout);
081b2d
@@ -2992,11 +3029,11 @@ agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn)
081b2d
                  * temporarily mark it as "unavailable".
081b2d
                  */
081b2d
                 slapi_ch_free_string(&agmt->maxcsn);
081b2d
-                agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(agmt->replarea),
081b2d
+                agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%ld;unavailable", slapi_sdn_get_dn(agmt->replarea),
081b2d
                                                  slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(agmt->rdn)), agmt->hostname, agmt->port);
081b2d
             } else if (rid == oprid) {
081b2d
                 slapi_ch_free_string(&agmt->maxcsn);
081b2d
-                agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%d;%d;%s", slapi_sdn_get_dn(agmt->replarea),
081b2d
+                agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%ld;%d;%s", slapi_sdn_get_dn(agmt->replarea),
081b2d
                                                  slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(agmt->rdn)), agmt->hostname,
081b2d
                                                  agmt->port, agmt->consumerRID, maxcsn);
081b2d
             }
081b2d
@@ -3190,10 +3227,10 @@ agmt_remove_maxcsn(Repl_Agmt *ra)
081b2d
                     char unavail_buf[BUFSIZ];
081b2d
                     struct berval val;
081b2d
 
081b2d
-                    PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%d;", slapi_sdn_get_dn(ra->replarea),
081b2d
+                    PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%ld;", slapi_sdn_get_dn(ra->replarea),
081b2d
                                 slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)),
081b2d
                                 ra->hostname, ra->port);
081b2d
-                    PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%d;unavailable",
081b2d
+                    PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%ld;unavailable",
081b2d
                                 slapi_sdn_get_dn(ra->replarea),
081b2d
                                 slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)),
081b2d
                                 ra->hostname, ra->port);
081b2d
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
081b2d
index 92f847f24..e5296bf1c 100644
081b2d
--- a/ldap/servers/plugins/replication/repl5_replica.c
081b2d
+++ b/ldap/servers/plugins/replication/repl5_replica.c
081b2d
@@ -33,42 +33,40 @@ struct replica
081b2d
     Slapi_DN *repl_root;               /* top of the replicated are */
081b2d
     char *repl_name;                   /* unique replica name */
081b2d
     PRBool new_name;                   /* new name was generated - need to be saved */
081b2d
-    ReplicaUpdateDNList updatedn_list; /* list of dns with which a supplier should bind
081b2d
-                           to update this replica                */
081b2d
-    Slapi_ValueSet *updatedn_groups;   /* set of groups whose memebers are
081b2d
-                                * allowed to update replica */
081b2d
+    ReplicaUpdateDNList updatedn_list; /* list of dns with which a supplier should bind to update this replica */
081b2d
+    Slapi_ValueSet *updatedn_groups;   /* set of groups whose memebers are allowed to update replica */
081b2d
     ReplicaUpdateDNList groupdn_list;  /* exploded listof dns from update group */
081b2d
-    PRUint32 updatedn_group_last_check;
081b2d
-    int updatedn_group_check_interval;
081b2d
-    ReplicaType repl_type;           /* is this replica read-only ?            */
081b2d
-    ReplicaId repl_rid;              /* replicaID                            */
081b2d
-    Object *repl_ruv;                /* replica update vector                */
081b2d
-    PRBool repl_ruv_dirty;           /* Dirty flag for ruv                   */
081b2d
-    CSNPL *min_csn_pl;               /* Pending list for minimal CSN         */
081b2d
-    void *csn_pl_reg_id;             /* registration assignment for csn callbacks */
081b2d
-    unsigned long repl_state_flags;  /* state flags                            */
081b2d
-    PRUint32 repl_flags;             /* persistent, externally visible flags */
081b2d
-    PRMonitor *repl_lock;            /* protects entire structure            */
081b2d
-    Slapi_Eq_Context repl_eqcxt_rs;  /* context to cancel event that saves ruv */
081b2d
-    Slapi_Eq_Context repl_eqcxt_tr;  /* context to cancel event that reaps tombstones */
081b2d
-    Object *repl_csngen;             /* CSN generator for this replica */
081b2d
-    PRBool repl_csn_assigned;        /* Flag set when new csn is assigned. */
081b2d
-    PRUint32 repl_purge_delay;       /* When purgeable, CSNs are held on to for this many extra seconds */
081b2d
-    PRBool tombstone_reap_stop;      /* TRUE when the tombstone reaper should stop */
081b2d
-    PRBool tombstone_reap_active;    /* TRUE when the tombstone reaper is running */
081b2d
-    long tombstone_reap_interval;    /* Time in seconds between tombstone reaping */
081b2d
-    Slapi_ValueSet *repl_referral;   /* A list of administrator provided referral URLs */
081b2d
-    PRBool state_update_inprogress;  /* replica state is being updated */
081b2d
-    PRLock *agmt_lock;               /* protects agreement creation, start and stop */
081b2d
-    char *locking_purl;              /* supplier who has exclusive access */
081b2d
-    uint64_t locking_conn;           /* The supplier's connection id */
081b2d
-    Slapi_Counter *protocol_timeout; /* protocol shutdown timeout */
081b2d
-    Slapi_Counter *backoff_min;      /* backoff retry minimum */
081b2d
-    Slapi_Counter *backoff_max;      /* backoff retry maximum */
081b2d
-    Slapi_Counter *precise_purging;  /* Enable precise tombstone purging */
081b2d
-    PRUint64 agmt_count;             /* Number of agmts */
081b2d
-    Slapi_Counter *release_timeout;  /* The amount of time to wait before releasing active replica */
081b2d
-    PRUint64 abort_session;          /* Abort the current replica session */
081b2d
+    uint32_t updatedn_group_last_check;    /* the time of the last group check */
081b2d
+    int64_t updatedn_group_check_interval; /* the group check interval */
081b2d
+    ReplicaType repl_type;             /* is this replica read-only ? */
081b2d
+    ReplicaId repl_rid;                /* replicaID */
081b2d
+    Object *repl_ruv;                  /* replica update vector */
081b2d
+    PRBool repl_ruv_dirty;             /* Dirty flag for ruv */
081b2d
+    CSNPL *min_csn_pl;                 /* Pending list for minimal CSN */
081b2d
+    void *csn_pl_reg_id;               /* registration assignment for csn callbacks */
081b2d
+    unsigned long repl_state_flags;    /* state flags */
081b2d
+    uint32_t repl_flags;               /* persistent, externally visible flags */
081b2d
+    PRMonitor *repl_lock;              /* protects entire structure */
081b2d
+    Slapi_Eq_Context repl_eqcxt_rs;    /* context to cancel event that saves ruv */
081b2d
+    Slapi_Eq_Context repl_eqcxt_tr;    /* context to cancel event that reaps tombstones */
081b2d
+    Object *repl_csngen;               /* CSN generator for this replica */
081b2d
+    PRBool repl_csn_assigned;          /* Flag set when new csn is assigned. */
081b2d
+    int64_t repl_purge_delay;          /* When purgeable, CSNs are held on to for this many extra seconds */
081b2d
+    PRBool tombstone_reap_stop;        /* TRUE when the tombstone reaper should stop */
081b2d
+    PRBool tombstone_reap_active;      /* TRUE when the tombstone reaper is running */
081b2d
+    int64_t tombstone_reap_interval;   /* Time in seconds between tombstone reaping */
081b2d
+    Slapi_ValueSet *repl_referral;     /* A list of administrator provided referral URLs */
081b2d
+    PRBool state_update_inprogress;    /* replica state is being updated */
081b2d
+    PRLock *agmt_lock;                 /* protects agreement creation, start and stop */
081b2d
+    char *locking_purl;                /* supplier who has exclusive access */
081b2d
+    uint64_t locking_conn;             /* The supplier's connection id */
081b2d
+    Slapi_Counter *protocol_timeout;   /* protocol shutdown timeout */
081b2d
+    Slapi_Counter *backoff_min;        /* backoff retry minimum */
081b2d
+    Slapi_Counter *backoff_max;        /* backoff retry maximum */
081b2d
+    Slapi_Counter *precise_purging;    /* Enable precise tombstone purging */
081b2d
+    uint64_t agmt_count;               /* Number of agmts */
081b2d
+    Slapi_Counter *release_timeout;    /* The amount of time to wait before releasing active replica */
081b2d
+    uint64_t abort_session;            /* Abort the current replica session */
081b2d
 };
081b2d
 
081b2d
 
081b2d
@@ -532,7 +530,7 @@ replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid)
081b2d
  * current_purl is the supplier who already has access, if any
081b2d
  */
081b2d
 PRBool
081b2d
-replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opid, const char *locking_purl, char **current_purl)
081b2d
+replica_get_exclusive_access(Replica *r, PRBool *isInc, uint64_t connid, int opid, const char *locking_purl, char **current_purl)
081b2d
 {
081b2d
     PRBool rval = PR_TRUE;
081b2d
 
081b2d
@@ -608,7 +606,7 @@ done:
081b2d
  * Relinquish exclusive access to the replica
081b2d
  */
081b2d
 void
081b2d
-replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid)
081b2d
+replica_relinquish_exclusive_access(Replica *r, uint64_t connid, int opid)
081b2d
 {
081b2d
     PRBool isInc;
081b2d
 
081b2d
@@ -915,7 +913,7 @@ replica_get_type(const Replica *r)
081b2d
     return r->repl_type;
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 replica_get_protocol_timeout(Replica *r)
081b2d
 {
081b2d
     if (r) {
081b2d
@@ -925,7 +923,7 @@ replica_get_protocol_timeout(Replica *r)
081b2d
     }
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 replica_get_release_timeout(Replica *r)
081b2d
 {
081b2d
     if (r) {
081b2d
@@ -936,7 +934,7 @@ replica_get_release_timeout(Replica *r)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_release_timeout(Replica *r, PRUint64 limit)
081b2d
+replica_set_release_timeout(Replica *r, uint64_t limit)
081b2d
 {
081b2d
     if (r) {
081b2d
         slapi_counter_set_value(r->release_timeout, limit);
081b2d
@@ -944,7 +942,7 @@ replica_set_release_timeout(Replica *r, PRUint64 limit)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_protocol_timeout(Replica *r, PRUint64 timeout)
081b2d
+replica_set_protocol_timeout(Replica *r, uint64_t timeout)
081b2d
 {
081b2d
     if (r) {
081b2d
         slapi_counter_set_value(r->protocol_timeout, timeout);
081b2d
@@ -1182,7 +1180,7 @@ replica_get_generation(const Replica *r)
081b2d
 }
081b2d
 
081b2d
 PRBool
081b2d
-replica_is_flag_set(const Replica *r, PRUint32 flag)
081b2d
+replica_is_flag_set(const Replica *r, uint32_t flag)
081b2d
 {
081b2d
     if (r)
081b2d
         return (r->repl_flags & flag);
081b2d
@@ -1191,7 +1189,7 @@ replica_is_flag_set(const Replica *r, PRUint32 flag)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_flag(Replica *r, PRUint32 flag, PRBool clear)
081b2d
+replica_set_flag(Replica *r, uint32_t flag, PRBool clear)
081b2d
 {
081b2d
     if (r == NULL)
081b2d
         return;
081b2d
@@ -1208,7 +1206,7 @@ replica_set_flag(Replica *r, PRUint32 flag, PRBool clear)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_replace_flags(Replica *r, PRUint32 flags)
081b2d
+replica_replace_flags(Replica *r, uint32_t flags)
081b2d
 {
081b2d
     if (r) {
081b2d
         replica_lock(r->repl_lock);
081b2d
@@ -1829,17 +1827,18 @@ _replica_check_validity(const Replica *r)
081b2d
 static int
081b2d
 _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
 {
081b2d
-    Slapi_Attr *a = NULL;
081b2d
     Slapi_Attr *attr;
081b2d
     CSNGen *gen;
081b2d
     char *precise_purging = NULL;
081b2d
     char buf[SLAPI_DSE_RETURNTEXT_SIZE];
081b2d
     char *errormsg = errortext ? errortext : buf;
081b2d
     char *val;
081b2d
-    int backoff_min;
081b2d
-    int backoff_max;
081b2d
-    int ptimeout = 0;
081b2d
-    int release_timeout = 0;
081b2d
+    int64_t backoff_min;
081b2d
+    int64_t backoff_max;
081b2d
+    int64_t ptimeout = 0;
081b2d
+    int64_t release_timeout = 0;
081b2d
+    int64_t interval = 0;
081b2d
+    int64_t rtype = 0;
081b2d
     int rc;
081b2d
 
081b2d
     PR_ASSERT(r && e);
081b2d
@@ -1847,7 +1846,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
     /* get replica root */
081b2d
     val = slapi_entry_attr_get_charptr(e, attr_replicaRoot);
081b2d
     if (val == NULL) {
081b2d
-        PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to retrieve %s attribute from (%s)\n",
081b2d
+        PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to retrieve %s attribute from (%s)",
081b2d
                     attr_replicaRoot,
081b2d
                     (char *)slapi_entry_get_dn((Slapi_Entry *)e));
081b2d
         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - %s\n",
081b2d
@@ -1858,66 +1857,94 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
     r->repl_root = slapi_sdn_new_dn_passin(val);
081b2d
 
081b2d
     /* get replica type */
081b2d
-    val = slapi_entry_attr_get_charptr(e, attr_replicaType);
081b2d
-    if (val) {
081b2d
-        r->repl_type = atoi(val);
081b2d
-        slapi_ch_free((void **)&val;;
081b2d
+    if (slapi_entry_attr_exists(e, attr_replicaType)) {
081b2d
+        if ((val = slapi_entry_attr_get_charptr(e, attr_replicaType))) {
081b2d
+            if (repl_config_valid_num(attr_replicaType, val, 0, REPLICA_TYPE_UPDATABLE, &rc, errormsg, &rtype) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
+                return -1;
081b2d
+            }
081b2d
+            r->repl_type = rtype;
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+        } else {
081b2d
+            r->repl_type = REPLICA_TYPE_READONLY;
081b2d
+        }
081b2d
     } else {
081b2d
         r->repl_type = REPLICA_TYPE_READONLY;
081b2d
     }
081b2d
 
081b2d
-    /* grab and validate the backoff retry settings */
081b2d
+    /* grab and validate the backoff min retry settings */
081b2d
     if (slapi_entry_attr_exists(e, type_replicaBackoffMin)) {
081b2d
-        backoff_min = slapi_entry_attr_get_int(e, type_replicaBackoffMin);
081b2d
-        if (backoff_min <= 0) {
081b2d
-            slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - "
081b2d
-                                                               "Invalid value for %s: %d  Using default value (%d)\n",
081b2d
-                          type_replicaBackoffMin, backoff_min, PROTOCOL_BACKOFF_MINIMUM);
081b2d
+        if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMin))) {
081b2d
+            if (repl_config_valid_num(type_replicaBackoffMin, val, 1, INT_MAX, &rc, errormsg, &backoff_min) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
+                return -1;
081b2d
+            }
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+        } else {
081b2d
             backoff_min = PROTOCOL_BACKOFF_MINIMUM;
081b2d
         }
081b2d
     } else {
081b2d
         backoff_min = PROTOCOL_BACKOFF_MINIMUM;
081b2d
     }
081b2d
 
081b2d
+    /* grab and validate the backoff max retry settings */
081b2d
     if (slapi_entry_attr_exists(e, type_replicaBackoffMax)) {
081b2d
-        backoff_max = slapi_entry_attr_get_int(e, type_replicaBackoffMax);
081b2d
-        if (backoff_max <= 0) {
081b2d
-            slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - "
081b2d
-                                                               "Invalid value for %s: %d  Using default value (%d)\n",
081b2d
-                          type_replicaBackoffMax, backoff_max, PROTOCOL_BACKOFF_MAXIMUM);
081b2d
+        if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMax))) {
081b2d
+            if (repl_config_valid_num(type_replicaBackoffMax, val, 1, INT_MAX, &rc, errormsg, &backoff_max) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
+                return -1;
081b2d
+            }
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+        } else {
081b2d
             backoff_max = PROTOCOL_BACKOFF_MAXIMUM;
081b2d
         }
081b2d
     } else {
081b2d
         backoff_max = PROTOCOL_BACKOFF_MAXIMUM;
081b2d
     }
081b2d
 
081b2d
+    /* Verify backoff min and max work together */
081b2d
     if (backoff_min > backoff_max) {
081b2d
-        /* Ok these values are invalid, reset back the defaults */
081b2d
-        slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - "
081b2d
-                                                           "Backoff minimum (%d) can not be greater than "
081b2d
-                                                           "the backoff maximum (%d).  Using default values: min (%d) max (%d)\n",
081b2d
-                      backoff_min, backoff_max, PROTOCOL_BACKOFF_MINIMUM, PROTOCOL_BACKOFF_MAXIMUM);
081b2d
-        slapi_counter_set_value(r->backoff_min, PROTOCOL_BACKOFF_MINIMUM);
081b2d
-        slapi_counter_set_value(r->backoff_max, PROTOCOL_BACKOFF_MAXIMUM);
081b2d
+        PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
+                    "Backoff minimum (%ld) can not be greater than the backoff maximum (%ld).",
081b2d
+                    backoff_min, backoff_max);
081b2d
+        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - "
081b2d
+                      "%s\n", errormsg);
081b2d
+        return -1;
081b2d
     } else {
081b2d
         slapi_counter_set_value(r->backoff_min, backoff_min);
081b2d
         slapi_counter_set_value(r->backoff_max, backoff_max);
081b2d
     }
081b2d
 
081b2d
     /* get the protocol timeout */
081b2d
-    ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
081b2d
-    if (ptimeout <= 0) {
081b2d
-        slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
081b2d
+    if (slapi_entry_attr_exists(e, type_replicaProtocolTimeout)) {
081b2d
+        if ((val = slapi_entry_attr_get_charptr(e, type_replicaProtocolTimeout))) {
081b2d
+            if (repl_config_valid_num(type_replicaProtocolTimeout, val, 0, INT_MAX, &rc, errormsg, &ptimeout) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
+                return -1;
081b2d
+            }
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+            slapi_counter_set_value(r->protocol_timeout, ptimeout);
081b2d
+        } else {
081b2d
+            slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
081b2d
+        }
081b2d
     } else {
081b2d
-        slapi_counter_set_value(r->protocol_timeout, ptimeout);
081b2d
+        slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
081b2d
     }
081b2d
 
081b2d
     /* Get the release timeout */
081b2d
-    release_timeout = slapi_entry_attr_get_int(e, type_replicaReleaseTimeout);
081b2d
-    if (release_timeout <= 0) {
081b2d
-        slapi_counter_set_value(r->release_timeout, 0);
081b2d
+    if (slapi_entry_attr_exists(e, type_replicaReleaseTimeout)) {
081b2d
+        if ((val = slapi_entry_attr_get_charptr(e, type_replicaReleaseTimeout))) {
081b2d
+            if (repl_config_valid_num(type_replicaReleaseTimeout, val, 0, INT_MAX, &rc, errortext, &release_timeout) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
+                return -1;
081b2d
+            }
081b2d
+            slapi_counter_set_value(r->release_timeout, release_timeout);
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+        } else {
081b2d
+            slapi_counter_set_value(r->release_timeout, 0);
081b2d
+        }
081b2d
     } else {
081b2d
-        slapi_counter_set_value(r->release_timeout, release_timeout);
081b2d
+        slapi_counter_set_value(r->release_timeout, 0);
081b2d
     }
081b2d
 
081b2d
     /* check for precise tombstone purging */
081b2d
@@ -1929,10 +1956,11 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
             slapi_counter_set_value(r->precise_purging, 0);
081b2d
         } else {
081b2d
             /* Invalid value */
081b2d
-            slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - "
081b2d
-                                                               "Invalid value for %s: %s  Using default value (off)\n",
081b2d
-                          type_replicaPrecisePurge, precise_purging);
081b2d
-            slapi_counter_set_value(r->precise_purging, 0);
081b2d
+            PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for %s: %s",
081b2d
+                        type_replicaPrecisePurge, precise_purging);
081b2d
+            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - "
081b2d
+                          "%s\n", errormsg);
081b2d
+            return -1;
081b2d
         }
081b2d
         slapi_ch_free_string(&precise_purging);
081b2d
     } else {
081b2d
@@ -1940,7 +1968,19 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
     }
081b2d
 
081b2d
     /* get replica flags */
081b2d
-    r->repl_flags = slapi_entry_attr_get_ulong(e, attr_flags);
081b2d
+    if (slapi_entry_attr_exists(e, attr_flags)) {
081b2d
+        int64_t rflags;
081b2d
+        if((val = slapi_entry_attr_get_charptr(e, attr_flags))) {
081b2d
+            if (repl_config_valid_num(attr_flags, val, 0, 1, &rc, errortext, &rflags) != 0) {
081b2d
+                return -1;
081b2d
+            }
081b2d
+            r->repl_flags = (uint32_t)rflags;
081b2d
+        } else {
081b2d
+            r->repl_flags = 0;
081b2d
+        }
081b2d
+    } else {
081b2d
+        r->repl_flags = 0;
081b2d
+    }
081b2d
 
081b2d
     /*
081b2d
      * Get replicaid
081b2d
@@ -1955,20 +1995,13 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
     else if (r->repl_type == REPLICA_TYPE_UPDATABLE ||
081b2d
              r->repl_type == REPLICA_TYPE_PRIMARY) {
081b2d
         if ((val = slapi_entry_attr_get_charptr(e, attr_replicaId))) {
081b2d
-            int temprid = atoi(val);
081b2d
-            slapi_ch_free((void **)&val;;
081b2d
-            if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID) {
081b2d
-                PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                            "Attribute %s must have a value greater than 0 "
081b2d
-                            "and less than %d: entry %s",
081b2d
-                            attr_replicaId, READ_ONLY_REPLICA_ID,
081b2d
-                            (char *)slapi_entry_get_dn((Slapi_Entry *)e));
081b2d
-                slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
081b2d
-                              "_replica_init_from_config - %s\n", errormsg);
081b2d
+            int64_t rid;
081b2d
+            if (repl_config_valid_num(attr_replicaId, val, 1, 65535, &rc, errormsg, &rid) != 0) {
081b2d
+                slapi_ch_free_string(&val;;
081b2d
                 return -1;
081b2d
-            } else {
081b2d
-                r->repl_rid = (ReplicaId)temprid;
081b2d
             }
081b2d
+            r->repl_rid = (ReplicaId)rid;
081b2d
+            slapi_ch_free_string(&val;;
081b2d
         } else {
081b2d
             PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
                         "Failed to retrieve required %s attribute from %s",
081b2d
@@ -2003,10 +2036,13 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
     r->groupdn_list = replica_groupdn_list_new(r->updatedn_groups);
081b2d
     r->updatedn_group_last_check = time(NULL);
081b2d
     /* get groupdn check interval */
081b2d
-    val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval);
081b2d
-    if (val) {
081b2d
-        r->updatedn_group_check_interval = atoi(val);
081b2d
-        slapi_ch_free((void **)&val;;
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval))) {
081b2d
+        if (repl_config_valid_num(attr_replicaBindDnGroupCheckInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) {
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+            return -1;
081b2d
+        }
081b2d
+        r->updatedn_group_check_interval = interval;
081b2d
+        slapi_ch_free_string(&val;;
081b2d
     } else {
081b2d
         r->updatedn_group_check_interval = -1;
081b2d
     }
081b2d
@@ -2041,18 +2077,26 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
081b2d
      * since we don't know about LCUP replicas, and they can just
081b2d
      * turn up whenever they want to.
081b2d
      */
081b2d
-    if (slapi_entry_attr_find(e, type_replicaPurgeDelay, &a) == -1) {
081b2d
-        /* No purge delay provided, so use default */
081b2d
-        r->repl_purge_delay = 60 * 60 * 24 * 7; /* One week, in seconds */
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_replicaPurgeDelay))) {
081b2d
+        if (repl_config_valid_num(type_replicaPurgeDelay, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) {
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+            return -1;
081b2d
+        }
081b2d
+        r->repl_purge_delay = interval;
081b2d
+        slapi_ch_free_string(&val;;
081b2d
     } else {
081b2d
-        r->repl_purge_delay = slapi_entry_attr_get_uint(e, type_replicaPurgeDelay);
081b2d
+        r->repl_purge_delay = 60 * 60 * 24 * 7; /* One week, in seconds */
081b2d
     }
081b2d
 
081b2d
-    if (slapi_entry_attr_find(e, type_replicaTombstonePurgeInterval, &a) == -1) {
081b2d
-        /* No reap interval provided, so use default */
081b2d
-        r->tombstone_reap_interval = 3600 * 24; /* One day */
081b2d
+    if ((val = slapi_entry_attr_get_charptr(e, type_replicaTombstonePurgeInterval))) {
081b2d
+        if (repl_config_valid_num(type_replicaTombstonePurgeInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) {
081b2d
+            slapi_ch_free_string(&val;;
081b2d
+            return -1;
081b2d
+        }
081b2d
+        r->tombstone_reap_interval = interval;
081b2d
+        slapi_ch_free_string(&val;;
081b2d
     } else {
081b2d
-        r->tombstone_reap_interval = slapi_entry_attr_get_int(e, type_replicaTombstonePurgeInterval);
081b2d
+        r->tombstone_reap_interval = 3600 * 24; /* One week, in seconds */
081b2d
     }
081b2d
 
081b2d
     r->tombstone_reap_stop = r->tombstone_reap_active = PR_FALSE;
081b2d
@@ -3534,7 +3578,7 @@ replica_log_ruv_elements_nolock(const Replica *r)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_purge_delay(Replica *r, PRUint32 purge_delay)
081b2d
+replica_set_purge_delay(Replica *r, uint32_t purge_delay)
081b2d
 {
081b2d
     PR_ASSERT(r);
081b2d
     replica_lock(r->repl_lock);
081b2d
@@ -3710,7 +3754,7 @@ replica_set_ruv_dirty(Replica *r)
081b2d
 }
081b2d
 
081b2d
 PRBool
081b2d
-replica_is_state_flag_set(Replica *r, PRInt32 flag)
081b2d
+replica_is_state_flag_set(Replica *r, int32_t flag)
081b2d
 {
081b2d
     PR_ASSERT(r);
081b2d
     if (r)
081b2d
@@ -3720,7 +3764,7 @@ replica_is_state_flag_set(Replica *r, PRInt32 flag)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_state_flag(Replica *r, PRUint32 flag, PRBool clear)
081b2d
+replica_set_state_flag(Replica *r, uint32_t flag, PRBool clear)
081b2d
 {
081b2d
     if (r == NULL)
081b2d
         return;
081b2d
@@ -3994,7 +4038,7 @@ replica_get_attr(Slapi_PBlock *pb, const char *type, void *value)
081b2d
     return rc;
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 replica_get_backoff_min(Replica *r)
081b2d
 {
081b2d
     if (r) {
081b2d
@@ -4004,7 +4048,7 @@ replica_get_backoff_min(Replica *r)
081b2d
     }
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 replica_get_backoff_max(Replica *r)
081b2d
 {
081b2d
     if (r) {
081b2d
@@ -4015,7 +4059,7 @@ replica_get_backoff_max(Replica *r)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_backoff_min(Replica *r, PRUint64 min)
081b2d
+replica_set_backoff_min(Replica *r, uint64_t min)
081b2d
 {
081b2d
     if (r) {
081b2d
         slapi_counter_set_value(r->backoff_min, min);
081b2d
@@ -4023,7 +4067,7 @@ replica_set_backoff_min(Replica *r, PRUint64 min)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_backoff_max(Replica *r, PRUint64 max)
081b2d
+replica_set_backoff_max(Replica *r, uint64_t max)
081b2d
 {
081b2d
     if (r) {
081b2d
         slapi_counter_set_value(r->backoff_max, max);
081b2d
@@ -4031,14 +4075,14 @@ replica_set_backoff_max(Replica *r, PRUint64 max)
081b2d
 }
081b2d
 
081b2d
 void
081b2d
-replica_set_precise_purging(Replica *r, PRUint64 on_off)
081b2d
+replica_set_precise_purging(Replica *r, uint64_t on_off)
081b2d
 {
081b2d
     if (r) {
081b2d
         slapi_counter_set_value(r->precise_purging, on_off);
081b2d
     }
081b2d
 }
081b2d
 
081b2d
-PRUint64
081b2d
+uint64_t
081b2d
 replica_get_precise_purging(Replica *r)
081b2d
 {
081b2d
     if (r) {
081b2d
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
081b2d
index 7477a292c..9c3c75458 100644
081b2d
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
081b2d
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
081b2d
@@ -405,28 +405,35 @@ replica_config_modify(Slapi_PBlock *pb,
081b2d
                 } else if (strcasecmp(config_attr, attr_replicaBindDnGroup) == 0) {
081b2d
                     *returncode = replica_config_change_updatedngroup(r, mods[i], errortext, apply_mods);
081b2d
                 } else if (strcasecmp(config_attr, attr_replicaBindDnGroupCheckInterval) == 0) {
081b2d
-                    int interval = atoi(config_attr_value);
081b2d
-                    replica_set_groupdn_checkinterval(r, interval);
081b2d
+                    int64_t interval = 0;
081b2d
+                    if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &interval) == 0) {
081b2d
+                        replica_set_groupdn_checkinterval(r, interval);
081b2d
+                    } else {
081b2d
+                        break;
081b2d
+                    }
081b2d
                 } else if (strcasecmp(config_attr, attr_replicaType) == 0) {
081b2d
+                    int64_t rtype;
081b2d
                     slapi_ch_free_string(&new_repl_type);
081b2d
-                    new_repl_type = slapi_ch_strdup(config_attr_value);
081b2d
+                    if (repl_config_valid_num(config_attr, config_attr_value, 1, 3, returncode, errortext, &rtype) == 0) {
081b2d
+                        new_repl_type = slapi_ch_strdup(config_attr_value);
081b2d
+                    } else {
081b2d
+                        break;
081b2d
+                    }
081b2d
                 } else if (strcasecmp(config_attr, attr_replicaId) == 0) {
081b2d
-                    char *endp = NULL;
081b2d
                     int64_t rid = 0;
081b2d
-                    errno = 0;
081b2d
-                    rid = strtoll(config_attr_value, &endp, 10);
081b2d
-                    if (*endp != '\0' || rid > 65535 || rid < 1 || errno == ERANGE) {
081b2d
-                        *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                        PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                            "Attribute %s value (%s) is invalid, must be a number between 1 and 65535.\n",
081b2d
-                            config_attr, config_attr_value);
081b2d
-                        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                    if (repl_config_valid_num(config_attr, config_attr_value, 1, 65535, returncode, errortext, &rid) == 0) {
081b2d
+                        slapi_ch_free_string(&new_repl_id);
081b2d
+                        new_repl_id = slapi_ch_strdup(config_attr_value);
081b2d
+                    } else {
081b2d
                         break;
081b2d
                     }
081b2d
-                    slapi_ch_free_string(&new_repl_id);
081b2d
-                    new_repl_id = slapi_ch_strdup(config_attr_value);
081b2d
                 } else if (strcasecmp(config_attr, attr_flags) == 0) {
081b2d
-                    *returncode = replica_config_change_flags(r, config_attr_value, errortext, apply_mods);
081b2d
+                    int64_t rflags = 0;
081b2d
+                    if (repl_config_valid_num(config_attr, config_attr_value, 0, 1, returncode, errortext, &rflags) == 0) {
081b2d
+                        *returncode = replica_config_change_flags(r, config_attr_value, errortext, apply_mods);
081b2d
+                    } else {
081b2d
+                        break;
081b2d
+                    }
081b2d
                 } else if (strcasecmp(config_attr, TASK_ATTR) == 0) {
081b2d
                     *returncode = replica_execute_task(mtnode_ext->replica, config_attr_value, errortext, apply_mods);
081b2d
                 } else if (strcasecmp(config_attr, attr_replicaReferral) == 0) {
081b2d
@@ -442,18 +449,21 @@ replica_config_modify(Slapi_PBlock *pb,
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaPurgeDelay) == 0) {
081b2d
                     if (apply_mods && config_attr_value[0]) {
081b2d
-                        PRUint32 delay;
081b2d
-                        if (isdigit(config_attr_value[0])) {
081b2d
-                            delay = (unsigned int)atoi(config_attr_value);
081b2d
+                        int64_t delay = 0;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &delay) == 0) {
081b2d
                             replica_set_purge_delay(r, delay);
081b2d
-                        } else
081b2d
-                            *returncode = LDAP_OPERATIONS_ERROR;
081b2d
+                        } else {
081b2d
+                            break;
081b2d
+                        }
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaTombstonePurgeInterval) == 0) {
081b2d
                     if (apply_mods && config_attr_value[0]) {
081b2d
-                        long interval;
081b2d
-                        interval = atol(config_attr_value);
081b2d
-                        replica_set_tombstone_reap_interval(r, interval);
081b2d
+                        int64_t interval;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &interval) == 0) {
081b2d
+                            replica_set_tombstone_reap_interval(r, interval);
081b2d
+                        } else {
081b2d
+                            break;
081b2d
+                        }
081b2d
                     }
081b2d
                 }
081b2d
                 /* ignore modifiers attributes added by the server */
081b2d
@@ -461,73 +471,55 @@ replica_config_modify(Slapi_PBlock *pb,
081b2d
                     *returncode = LDAP_SUCCESS;
081b2d
                 } else if (strcasecmp(config_attr, type_replicaProtocolTimeout) == 0) {
081b2d
                     if (apply_mods) {
081b2d
-                        PRUint64 ptimeout = 0;
081b2d
-
081b2d
-                        ptimeout = atoll(config_attr_value);
081b2d
-
081b2d
-                        if (ptimeout <= 0) {
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number greater than zero.\n",
081b2d
-                                        config_attr, config_attr_value);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                        int64_t ptimeout = 0;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &ptimeout) == 0) {
081b2d
+                            replica_set_protocol_timeout(r, ptimeout);
081b2d
+                        } else {
081b2d
                             break;
081b2d
                         }
081b2d
-                        replica_set_protocol_timeout(r, ptimeout);
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaBackoffMin) == 0) {
081b2d
                     if (apply_mods) {
081b2d
-                        uint64_t val = atoll(config_attr_value);
081b2d
-                        uint64_t max;
081b2d
-
081b2d
-                        if (val <= 0) {
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number greater than zero.\n",
081b2d
-                                        config_attr, config_attr_value);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
-                            break;
081b2d
-                        }
081b2d
-                        max = replica_get_backoff_max(r);
081b2d
-                        if (val > max){
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n",
081b2d
-                                        config_attr, config_attr_value, (int)max);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                        int64_t val = 0;
081b2d
+                        int64_t max;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) {
081b2d
+                            max = replica_get_backoff_max(r);
081b2d
+                            if (val > max){
081b2d
+                                *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
+                                PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
+                                            "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n",
081b2d
+                                            config_attr, config_attr_value, (int)max);
081b2d
+                                slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                                break;
081b2d
+                            }
081b2d
+                            replica_set_backoff_min(r, val);
081b2d
+                        } else {
081b2d
                             break;
081b2d
                         }
081b2d
-                        replica_set_backoff_min(r, val);
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaBackoffMax) == 0) {
081b2d
                     if (apply_mods) {
081b2d
-                        uint64_t val = atoll(config_attr_value);
081b2d
-                        uint64_t min;
081b2d
-
081b2d
-                        if (val <= 0) {
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number greater than zero.\n",
081b2d
-                                        config_attr, config_attr_value);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n",
081b2d
-                                          errortext);
081b2d
-                            break;
081b2d
-                        }
081b2d
-                        min = replica_get_backoff_min(r);
081b2d
-                        if (val < min) {
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n",
081b2d
-                                        config_attr, config_attr_value, (int)min);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                        int64_t val = 0;
081b2d
+                        int64_t min;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) {
081b2d
+                            min = replica_get_backoff_min(r);
081b2d
+                            if (val < min) {
081b2d
+                                *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
+                                PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
+                                            "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n",
081b2d
+                                            config_attr, config_attr_value, (int)min);
081b2d
+                                slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
081b2d
+                                break;
081b2d
+                            }
081b2d
+                            replica_set_backoff_max(r, val);
081b2d
+                        } else {
081b2d
                             break;
081b2d
                         }
081b2d
-                        replica_set_backoff_max(r, val);
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaPrecisePurge) == 0) {
081b2d
                     if (apply_mods) {
081b2d
                         if (config_attr_value[0]) {
081b2d
-                            PRUint64 on_off = 0;
081b2d
+                            uint64_t on_off = 0;
081b2d
 
081b2d
                             if (strcasecmp(config_attr_value, "on") == 0) {
081b2d
                                 on_off = 1;
081b2d
@@ -550,19 +542,11 @@ replica_config_modify(Slapi_PBlock *pb,
081b2d
                     }
081b2d
                 } else if (strcasecmp(config_attr, type_replicaReleaseTimeout) == 0) {
081b2d
                     if (apply_mods) {
081b2d
-                        long val = atol(config_attr_value);
081b2d
-
081b2d
-                        if (val < 0) {
081b2d
-                            *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
-                            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
-                                        "Attribute %s value (%s) is invalid, must be a number zero or greater.\n",
081b2d
-                                        config_attr, config_attr_value);
081b2d
-                            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
081b2d
-                                          "replica_config_modify - %s\n", errortext);
081b2d
-                            break;
081b2d
-                        } else {
081b2d
-                            /* Set the timeout */
081b2d
+                        int64_t val;
081b2d
+                        if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) {
081b2d
                             replica_set_release_timeout(r, val);
081b2d
+                        } else {
081b2d
+                            break;
081b2d
                         }
081b2d
                     }
081b2d
                 } else {
081b2d
@@ -1011,7 +995,7 @@ replica_config_change_flags(Replica *r, const char *new_flags, char *returntext
081b2d
     PR_ASSERT(r);
081b2d
 
081b2d
     if (apply_mods) {
081b2d
-        PRUint32 flags;
081b2d
+        uint32_t flags;
081b2d
 
081b2d
         flags = atol(new_flags);
081b2d
 
081b2d
diff --git a/ldap/servers/plugins/replication/replutil.c b/ldap/servers/plugins/replication/replutil.c
081b2d
index 1b0446788..7cc132362 100644
081b2d
--- a/ldap/servers/plugins/replication/replutil.c
081b2d
+++ b/ldap/servers/plugins/replication/replutil.c
081b2d
@@ -1061,3 +1061,29 @@ repl_set_repl_plugin_path(const char *path)
081b2d
 {
081b2d
     replpluginpath = slapi_ch_strdup(path);
081b2d
 }
081b2d
+
081b2d
+int
081b2d
+repl_config_valid_num(const char *config_attr, char *config_attr_value, int64_t min, int64_t max,
081b2d
+                      int *returncode, char *errortext, int64_t *retval)
081b2d
+{
081b2d
+    int rc = 0;
081b2d
+    char *endp = NULL;
081b2d
+    int64_t val;
081b2d
+    errno = 0;
081b2d
+
081b2d
+    val = strtol(config_attr_value, &endp, 10);
081b2d
+    if (*endp != '\0' || val < min || val > max || errno == ERANGE) {
081b2d
+        *returncode = LDAP_UNWILLING_TO_PERFORM;
081b2d
+        if (errortext){
081b2d
+            PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
081b2d
+                        "Attribute %s value (%s) is invalid, must be a number between %ld and %ld.",
081b2d
+                        config_attr, config_attr_value, min, max);
081b2d
+            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl_config_valid_num - %s\n",
081b2d
+                          errortext);
081b2d
+        }
081b2d
+        rc = -1;
081b2d
+    } else {
081b2d
+        *retval = val;
081b2d
+    }
081b2d
+    return rc;
081b2d
+}
081b2d
-- 
081b2d
2.13.6
081b2d