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

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