mirror of
https://git.centos.org/rpms/389-ds-base.git
synced 2025-02-24 00:32:54 +00:00
import 389-ds-base-1.3.10.1-2.el7
This commit is contained in:
commit
458e05c72c
13 changed files with 4432 additions and 0 deletions
1
.389-ds-base.metadata
Normal file
1
.389-ds-base.metadata
Normal file
|
@ -0,0 +1 @@
|
||||||
|
c995af6f5693f698c29b72ebfdbc0e60a72cc517 SOURCES/389-ds-base-1.3.10.1.tar.bz2
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SOURCES/389-ds-base-1.3.10.1.tar.bz2
|
|
@ -0,0 +1,53 @@
|
||||||
|
From 63fa3ee665b66b36321489c090b24811838837c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Tue, 3 Sep 2019 13:15:45 -0400
|
||||||
|
Subject: [PATCH] CVE-2019-14824 (BZ#1748199) - deref plugin displays
|
||||||
|
restricted attributes
|
||||||
|
|
||||||
|
Bug Description: If there is an ACI that allows "search" access to an attribute,
|
||||||
|
the deref plugin access control checks sees this is a "read"
|
||||||
|
privilege and returns the attribute's value.
|
||||||
|
|
||||||
|
Fix description: For deref plugin we are only concerned with "read" access, not
|
||||||
|
"search" access. Removed the SLAPI_ACL_SEARCH right flag when
|
||||||
|
checking access for an attribute.
|
||||||
|
|
||||||
|
Reviewed by: lkrispen & tbordaz(Thanks!)
|
||||||
|
---
|
||||||
|
ldap/servers/plugins/deref/deref.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c
|
||||||
|
index cb5ebb830..ec1884ba3 100644
|
||||||
|
--- a/ldap/servers/plugins/deref/deref.c
|
||||||
|
+++ b/ldap/servers/plugins/deref/deref.c
|
||||||
|
@@ -573,7 +573,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn,
|
||||||
|
Slapi_Entry **entries = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
- /* If the access check on the attributes is done without retrieveing the entry
|
||||||
|
+ /* If the access check on the attributes is done without retrieving the entry
|
||||||
|
* it cannot handle acis which need teh entry, eg to apply a targetfilter rule
|
||||||
|
* So the determination of attrs which can be dereferenced is delayed
|
||||||
|
*/
|
||||||
|
@@ -596,7 +596,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn,
|
||||||
|
int ii;
|
||||||
|
int needattrvals = 1; /* need attrvals sequence? */
|
||||||
|
if (deref_check_access(pb, entries[0], derefdn, attrs, &retattrs,
|
||||||
|
- (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) {
|
||||||
|
+ SLAPI_ACL_READ)) {
|
||||||
|
slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM,
|
||||||
|
"deref_do_deref_attr - The client does not have permission to read the requested "
|
||||||
|
"attributes in entry %s\n",
|
||||||
|
@@ -714,7 +714,7 @@ deref_pre_entry(Slapi_PBlock *pb)
|
||||||
|
attrs[1] = NULL;
|
||||||
|
|
||||||
|
if (deref_check_access(pb, ent, NULL, attrs, &retattrs,
|
||||||
|
- (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) {
|
||||||
|
+ SLAPI_ACL_READ)) {
|
||||||
|
slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM,
|
||||||
|
"deref_pre_entry - The client does not have permission to read attribute %s in entry %s\n",
|
||||||
|
spec->derefattr, slapi_entry_get_dn_const(ent));
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
From d33743c8604ff4f97947dad14fddab0691e3d19e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Thu, 1 Aug 2019 16:50:34 -0400
|
||||||
|
Subject: [PATCH] Issue 50525 - nsslapd-defaultnamingcontext does not change
|
||||||
|
when the assigned suffix gets deleted
|
||||||
|
|
||||||
|
Bug Description:
|
||||||
|
|
||||||
|
If you delete the suffix that is set as the default naming context, the attribute
|
||||||
|
is not reset.
|
||||||
|
|
||||||
|
Also using dsconf to delete a backend/suffix fails if there are vlv indexes, encrypted
|
||||||
|
attributes, or replication is configured.
|
||||||
|
|
||||||
|
Fix Description:
|
||||||
|
|
||||||
|
As for the default naming context, if there is a second suffix configured, it will be
|
||||||
|
automatically set as the new default naming context, otherwise the attribute is not
|
||||||
|
modified.
|
||||||
|
|
||||||
|
For dsconf backend delete issue, it now checks and removes replication configuration
|
||||||
|
and agreements, and removes all the child entries under the backend entry.
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/50525
|
||||||
|
|
||||||
|
Reviewed by: spichugi(Thanks!)
|
||||||
|
---
|
||||||
|
.../be_del_and_default_naming_attr_test.py | 90 +++++++++++++++++++
|
||||||
|
ldap/servers/slapd/mapping_tree.c | 50 ++++++-----
|
||||||
|
src/lib389/lib389/backend.py | 17 ++--
|
||||||
|
src/lib389/lib389/replica.py | 2 +-
|
||||||
|
4 files changed, 132 insertions(+), 27 deletions(-)
|
||||||
|
create mode 100644 dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..34a2de2ad
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
|
||||||
|
@@ -0,0 +1,90 @@
|
||||||
|
+import logging
|
||||||
|
+import pytest
|
||||||
|
+import os
|
||||||
|
+from lib389._constants import DEFAULT_SUFFIX
|
||||||
|
+from lib389.topologies import topology_m1 as topo
|
||||||
|
+from lib389.backend import Backends
|
||||||
|
+from lib389.encrypted_attributes import EncryptedAttrs
|
||||||
|
+
|
||||||
|
+DEBUGGING = os.getenv("DEBUGGING", default=False)
|
||||||
|
+if DEBUGGING:
|
||||||
|
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
|
||||||
|
+else:
|
||||||
|
+ logging.getLogger(__name__).setLevel(logging.INFO)
|
||||||
|
+log = logging.getLogger(__name__)
|
||||||
|
+
|
||||||
|
+SECOND_SUFFIX = 'o=namingcontext'
|
||||||
|
+THIRD_SUFFIX = 'o=namingcontext2'
|
||||||
|
+
|
||||||
|
+def test_be_delete(topo):
|
||||||
|
+ """Test that we can delete a backend that contains replication
|
||||||
|
+ configuration and encrypted attributes. The default naming
|
||||||
|
+ context should also be updated to reflect the next available suffix
|
||||||
|
+
|
||||||
|
+ :id: 5208f897-7c95-4925-bad0-9ceb95fee678
|
||||||
|
+ :setup: Master Instance
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Create second backend/suffix
|
||||||
|
+ 2. Add an encrypted attribute to the default suffix
|
||||||
|
+ 2. Delete default suffix
|
||||||
|
+ 3. Check the nsslapd-defaultnamingcontext is updated
|
||||||
|
+ 4. Delete the last backend
|
||||||
|
+ 5. Check the namingcontext has not changed
|
||||||
|
+ 6. Add new backend
|
||||||
|
+ 7. Set default naming context
|
||||||
|
+ 8. Verify the naming context is correct
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. Success
|
||||||
|
+ 3. Success
|
||||||
|
+ 4. Success
|
||||||
|
+ 5. Success
|
||||||
|
+ 6. Success
|
||||||
|
+ 7. Success
|
||||||
|
+ 8. Success
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ inst = topo.ms["master1"]
|
||||||
|
+
|
||||||
|
+ # Create second suffix
|
||||||
|
+ backends = Backends(inst)
|
||||||
|
+ default_backend = backends.get(DEFAULT_SUFFIX)
|
||||||
|
+ new_backend = backends.create(properties={'nsslapd-suffix': SECOND_SUFFIX,
|
||||||
|
+ 'name': 'namingRoot'})
|
||||||
|
+
|
||||||
|
+ # Add encrypted attribute entry under default suffix
|
||||||
|
+ encrypt_attrs = EncryptedAttrs(inst, basedn='cn=encrypted attributes,{}'.format(default_backend.dn))
|
||||||
|
+ encrypt_attrs.create(properties={'cn': 'employeeNumber', 'nsEncryptionAlgorithm': 'AES'})
|
||||||
|
+
|
||||||
|
+ # Delete default suffix
|
||||||
|
+ default_backend.delete()
|
||||||
|
+
|
||||||
|
+ # Check that the default naming context is set to the new/second suffix
|
||||||
|
+ default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
|
||||||
|
+ assert default_naming_ctx == SECOND_SUFFIX
|
||||||
|
+
|
||||||
|
+ # delete new backend, but the naming context should not change
|
||||||
|
+ new_backend.delete()
|
||||||
|
+
|
||||||
|
+ # Check that the default naming context is still set to the new/second suffix
|
||||||
|
+ default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
|
||||||
|
+ assert default_naming_ctx == SECOND_SUFFIX
|
||||||
|
+
|
||||||
|
+ # Add new backend
|
||||||
|
+ new_backend = backends.create(properties={'nsslapd-suffix': THIRD_SUFFIX,
|
||||||
|
+ 'name': 'namingRoot2'})
|
||||||
|
+
|
||||||
|
+ # manaully set naming context
|
||||||
|
+ inst.config.set('nsslapd-defaultnamingcontext', THIRD_SUFFIX)
|
||||||
|
+
|
||||||
|
+ # Verify naming context is correct
|
||||||
|
+ default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
|
||||||
|
+ assert default_naming_ctx == THIRD_SUFFIX
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+if __name__ == '__main__':
|
||||||
|
+ # Run isolated
|
||||||
|
+ # -s for DEBUG mode
|
||||||
|
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||||
|
+ pytest.main(["-s", CURRENT_FILE])
|
||||||
|
+
|
||||||
|
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
|
||||||
|
index 834949a67..25e9fb80c 100644
|
||||||
|
--- a/ldap/servers/slapd/mapping_tree.c
|
||||||
|
+++ b/ldap/servers/slapd/mapping_tree.c
|
||||||
|
@@ -1521,26 +1521,36 @@ done:
|
||||||
|
strcpy_unescape_value(escaped, suffix);
|
||||||
|
}
|
||||||
|
if (escaped && (0 == strcasecmp(escaped, default_naming_context))) {
|
||||||
|
- int rc = _mtn_update_config_param(LDAP_MOD_DELETE,
|
||||||
|
- CONFIG_DEFAULT_NAMING_CONTEXT,
|
||||||
|
- NULL);
|
||||||
|
- if (rc) {
|
||||||
|
- slapi_log_err(SLAPI_LOG_ERR,
|
||||||
|
- "mapping_tree_entry_delete_callback",
|
||||||
|
- "deleting config param %s failed: RC=%d\n",
|
||||||
|
- CONFIG_DEFAULT_NAMING_CONTEXT, rc);
|
||||||
|
- }
|
||||||
|
- if (LDAP_SUCCESS == rc) {
|
||||||
|
- char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE] = {0};
|
||||||
|
- /* Removing defaultNamingContext from cn=config entry
|
||||||
|
- * was successful. The remove does not reset the
|
||||||
|
- * global parameter. We need to reset it separately. */
|
||||||
|
- if (config_set_default_naming_context(
|
||||||
|
- CONFIG_DEFAULT_NAMING_CONTEXT,
|
||||||
|
- NULL, errorbuf, CONFIG_APPLY)) {
|
||||||
|
- slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_delete_callback",
|
||||||
|
- "Setting NULL to %s failed. %s\n",
|
||||||
|
- CONFIG_DEFAULT_NAMING_CONTEXT, errorbuf);
|
||||||
|
+ /*
|
||||||
|
+ * We can not delete the default naming attribute, so instead
|
||||||
|
+ * replace it only if there is another suffix available
|
||||||
|
+ */
|
||||||
|
+ void *node = NULL;
|
||||||
|
+ Slapi_DN *sdn;
|
||||||
|
+ sdn = slapi_get_first_suffix(&node, 0);
|
||||||
|
+ if (sdn) {
|
||||||
|
+ char *replacement_suffix = (char *)slapi_sdn_get_dn(sdn);
|
||||||
|
+ int rc = _mtn_update_config_param(LDAP_MOD_REPLACE,
|
||||||
|
+ CONFIG_DEFAULT_NAMING_CONTEXT,
|
||||||
|
+ replacement_suffix);
|
||||||
|
+ if (rc) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR,
|
||||||
|
+ "mapping_tree_entry_delete_callback",
|
||||||
|
+ "replacing config param %s failed: RC=%d\n",
|
||||||
|
+ CONFIG_DEFAULT_NAMING_CONTEXT, rc);
|
||||||
|
+ }
|
||||||
|
+ if (LDAP_SUCCESS == rc) {
|
||||||
|
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE] = {0};
|
||||||
|
+ /* Replacing defaultNamingContext from cn=config entry
|
||||||
|
+ * was successful. The replace does not reset the
|
||||||
|
+ * global parameter. We need to reset it separately. */
|
||||||
|
+ if (config_set_default_naming_context(
|
||||||
|
+ CONFIG_DEFAULT_NAMING_CONTEXT,
|
||||||
|
+ replacement_suffix, errorbuf, CONFIG_APPLY)) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_delete_callback",
|
||||||
|
+ "Setting %s tp %s failed. %s\n",
|
||||||
|
+ CONFIG_DEFAULT_NAMING_CONTEXT, replacement_suffix, errorbuf);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
|
||||||
|
index 6f4c8694e..4d32038f6 100644
|
||||||
|
--- a/src/lib389/lib389/backend.py
|
||||||
|
+++ b/src/lib389/lib389/backend.py
|
||||||
|
@@ -17,6 +17,7 @@ from lib389 import Entry
|
||||||
|
from lib389._mapped_object import DSLdapObjects, DSLdapObject
|
||||||
|
from lib389.mappingTree import MappingTrees, MappingTree
|
||||||
|
from lib389.exceptions import NoSuchEntryError, InvalidArgumentError
|
||||||
|
+from lib389.replica import Replicas
|
||||||
|
|
||||||
|
# We need to be a factor to the backend monitor
|
||||||
|
from lib389.monitor import MonitorBackend
|
||||||
|
@@ -507,20 +508,24 @@ class Backend(DSLdapObject):
|
||||||
|
mt = self._mts.get(selector=bename)
|
||||||
|
# Assert the type is "backend"
|
||||||
|
# Are these the right types....?
|
||||||
|
- if mt.get_attr_val('nsslapd-state') != ensure_bytes('backend'):
|
||||||
|
+ if mt.get_attr_val('nsslapd-state').lower() != ensure_bytes('backend'):
|
||||||
|
raise ldap.UNWILLING_TO_PERFORM('Can not delete the mapping tree, not for a backend! You may need to delete this backend via cn=config .... ;_; ')
|
||||||
|
+
|
||||||
|
+ # Delete replicas first
|
||||||
|
+ try:
|
||||||
|
+ Replicas(self._instance).get(mt.get_attr_val_utf8('cn')).delete()
|
||||||
|
+ except ldap.NO_SUCH_OBJECT:
|
||||||
|
+ # No replica, no problem
|
||||||
|
+ pass
|
||||||
|
+
|
||||||
|
# Delete our mapping tree if it exists.
|
||||||
|
mt.delete()
|
||||||
|
except ldap.NO_SUCH_OBJECT:
|
||||||
|
# Righto, it's already gone! Do nothing ...
|
||||||
|
pass
|
||||||
|
- # Delete all our related indices
|
||||||
|
- self._instance.index.delete_all(bename)
|
||||||
|
|
||||||
|
# Now remove our children, this is all ldbm config
|
||||||
|
- self._instance.delete_branch_s(self._dn, ldap.SCOPE_ONELEVEL)
|
||||||
|
- # The super will actually delete ourselves.
|
||||||
|
- super(Backend, self).delete()
|
||||||
|
+ self._instance.delete_branch_s(self._dn, ldap.SCOPE_SUBTREE)
|
||||||
|
|
||||||
|
def _lint_mappingtree(self):
|
||||||
|
"""Backend lint
|
||||||
|
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
|
||||||
|
index cdd0a9729..7b45683d9 100644
|
||||||
|
--- a/src/lib389/lib389/replica.py
|
||||||
|
+++ b/src/lib389/lib389/replica.py
|
||||||
|
@@ -458,7 +458,7 @@ class ReplicaLegacy(object):
|
||||||
|
try:
|
||||||
|
self.deleteAgreements(nsuffix)
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
- self.log.fatal('Failed to delete replica agreements!')
|
||||||
|
+ self.log.fatal('Failed to delete replica agreements! ' + str(e))
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Delete the replica
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
From 51ea1d34b861dfffb12fbe6be4e23d9342fd0fe2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Fri, 2 Aug 2019 14:36:24 -0400
|
||||||
|
Subject: [PATCH] Issue 50530 - Directory Server not RFC 4511 compliant with
|
||||||
|
requested attr "1.1"
|
||||||
|
|
||||||
|
Bug Description: A regression was introduced some time back that changed the
|
||||||
|
behavior of how the server handled the "1.1" requested attribute
|
||||||
|
in a search request. If "1.1" was requested along with other
|
||||||
|
attributes then no attibutes were returned, but in this case "1.1"
|
||||||
|
is expected to be ignroed.
|
||||||
|
|
||||||
|
Fix Description: Only comply with "1.1" if it is the only requested attribute
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/50530
|
||||||
|
|
||||||
|
Reviewed by: firstyear(Thanks!)
|
||||||
|
---
|
||||||
|
dirsrvtests/tests/suites/basic/basic_test.py | 57 +++++++++++++++++---
|
||||||
|
ldap/servers/slapd/result.c | 7 ++-
|
||||||
|
2 files changed, 57 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||||
|
index 0f7536b63..cea4f6bfe 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/basic/basic_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
|
||||||
|
@@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
|
||||||
|
USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
|
||||||
|
USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
|
||||||
|
USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
|
||||||
|
+USER4_DN = 'uid=user4,' + DEFAULT_SUFFIX
|
||||||
|
|
||||||
|
ROOTDSE_DEF_ATTR_LIST = ('namingContexts',
|
||||||
|
'supportedLDAPVersion',
|
||||||
|
@@ -409,8 +410,8 @@ def test_basic_acl(topology_st, import_example_ldif):
|
||||||
|
'uid': 'user1',
|
||||||
|
'userpassword': PASSWORD})))
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
- log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN
|
||||||
|
- + ': error ' + e.message['desc'])
|
||||||
|
+ log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
|
||||||
|
+ ': error ' + e.message['desc'])
|
||||||
|
assert False
|
||||||
|
|
||||||
|
try:
|
||||||
|
@@ -421,8 +422,8 @@ def test_basic_acl(topology_st, import_example_ldif):
|
||||||
|
'uid': 'user2',
|
||||||
|
'userpassword': PASSWORD})))
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
- log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN
|
||||||
|
- + ': error ' + e.message['desc'])
|
||||||
|
+ log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
|
||||||
|
+ ': error ' + e.message['desc'])
|
||||||
|
assert False
|
||||||
|
|
||||||
|
#
|
||||||
|
@@ -572,6 +573,50 @@ def test_basic_searches(topology_st, import_example_ldif):
|
||||||
|
log.info('test_basic_searches: PASSED')
|
||||||
|
|
||||||
|
|
||||||
|
+@pytest.fixture(scope="module")
|
||||||
|
+def add_test_entry(topology_st, request):
|
||||||
|
+ # Add test entry
|
||||||
|
+ topology_st.standalone.add_s(Entry((USER4_DN,
|
||||||
|
+ {'objectclass': "top extensibleObject".split(),
|
||||||
|
+ 'cn': 'user1', 'uid': 'user1'})))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+search_params = [(['1.1'], 'cn', False),
|
||||||
|
+ (['1.1', 'cn'], 'cn', True),
|
||||||
|
+ (['+'], 'nsUniqueId', True),
|
||||||
|
+ (['*'], 'cn', True),
|
||||||
|
+ (['cn'], 'cn', True)]
|
||||||
|
+@pytest.mark.parametrize("attrs, attr, present", search_params)
|
||||||
|
+def test_search_req_attrs(topology_st, add_test_entry, attrs, attr, present):
|
||||||
|
+ """Test requested attributes in search operations.
|
||||||
|
+ :id: 426a59ff-49b8-4a70-b377-0c0634a29b6e
|
||||||
|
+ :setup: Standalone instance
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Test "1.1" does not return any attributes.
|
||||||
|
+ 2. Test "1.1" is ignored if there are other requested attributes
|
||||||
|
+ 3. Test "+" returns all operational attributes
|
||||||
|
+ 4. Test "*" returns all attributes
|
||||||
|
+ 5. Test requested attributes
|
||||||
|
+
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. Success
|
||||||
|
+ 3. Success
|
||||||
|
+ 4. Success
|
||||||
|
+ 5. Success
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ log.info("Testing attrs: {} attr: {} present: {}".format(attrs, attr, present))
|
||||||
|
+ entry = topology_st.standalone.search_s(USER4_DN,
|
||||||
|
+ ldap.SCOPE_BASE,
|
||||||
|
+ 'objectclass=top',
|
||||||
|
+ attrs)
|
||||||
|
+ if present:
|
||||||
|
+ assert entry[0].hasAttr(attr)
|
||||||
|
+ else:
|
||||||
|
+ assert not entry[0].hasAttr(attr)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def test_basic_referrals(topology_st, import_example_ldif):
|
||||||
|
"""Test LDAP server in referral mode.
|
||||||
|
|
||||||
|
@@ -716,8 +761,8 @@ def test_basic_systemctl(topology_st, import_example_ldif):
|
||||||
|
log.info('Attempting to start the server with broken dse.ldif...')
|
||||||
|
try:
|
||||||
|
topology_st.standalone.start()
|
||||||
|
- except:
|
||||||
|
- log.info('Server failed to start as expected')
|
||||||
|
+ except Exception as e:
|
||||||
|
+ log.info('Server failed to start as expected: ' + str(e))
|
||||||
|
log.info('Check the status...')
|
||||||
|
assert (not topology_st.standalone.status())
|
||||||
|
log.info('Server failed to start as expected')
|
||||||
|
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
||||||
|
index d9f431cc5..34ddd8566 100644
|
||||||
|
--- a/ldap/servers/slapd/result.c
|
||||||
|
+++ b/ldap/servers/slapd/result.c
|
||||||
|
@@ -1546,6 +1546,8 @@ send_ldap_search_entry_ext(
|
||||||
|
* "+" means all operational attributes (rfc3673)
|
||||||
|
* operational attributes are only retrieved if they are named
|
||||||
|
* specifically or when "+" is specified.
|
||||||
|
+ * In the case of "1.1", if there are other requested attributes
|
||||||
|
+ * then "1.1" should be ignored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* figure out if we want all user attributes or no attributes at all */
|
||||||
|
@@ -1560,7 +1562,10 @@ send_ldap_search_entry_ext(
|
||||||
|
if (strcmp(LDAP_ALL_USER_ATTRS, attrs[i]) == 0) {
|
||||||
|
alluserattrs = 1;
|
||||||
|
} else if (strcmp(LDAP_NO_ATTRS, attrs[i]) == 0) {
|
||||||
|
- noattrs = 1;
|
||||||
|
+ /* "1.1" is only valid if it's the only requested attribute */
|
||||||
|
+ if (i == 0 && attrs[1] == NULL) {
|
||||||
|
+ noattrs = 1;
|
||||||
|
+ }
|
||||||
|
} else if (strcmp(LDAP_ALL_OPERATIONAL_ATTRS, attrs[i]) == 0) {
|
||||||
|
alloperationalattrs = 1;
|
||||||
|
} else {
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 606b7b6a45f6e2014119d0716774323f30862e0c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Fri, 2 Aug 2019 12:07:07 -0400
|
||||||
|
Subject: [PATCH] Issue 50529 - LDAP server returning PWP controls in
|
||||||
|
different sequence
|
||||||
|
|
||||||
|
Description: The server returns password policy controls in different orders
|
||||||
|
depending on the state of grace logins. The requested control,
|
||||||
|
if any, should be returned first, followed by any controls the
|
||||||
|
server might add.
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/50529
|
||||||
|
|
||||||
|
Reviewed by: mreynolds (one line commit rule)
|
||||||
|
---
|
||||||
|
ldap/servers/slapd/pw_mgmt.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
|
||||||
|
index befac50cd..ca76fc12f 100644
|
||||||
|
--- a/ldap/servers/slapd/pw_mgmt.c
|
||||||
|
+++ b/ldap/servers/slapd/pw_mgmt.c
|
||||||
|
@@ -207,10 +207,10 @@ skip:
|
||||||
|
|
||||||
|
/* password expired and user exceeded limit of grace attemps.
|
||||||
|
* Send result and also the control */
|
||||||
|
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||||
|
if (pwresponse_req) {
|
||||||
|
slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
|
||||||
|
}
|
||||||
|
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||||
|
slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
|
||||||
|
"password expired!", 0, NULL);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,682 @@
|
||||||
|
From 59f03e332061b2c68bb53eed5949ddcfdc563300 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Wed, 7 Aug 2019 20:36:53 -0400
|
||||||
|
Subject: [PATCH] Issue 50538 - cleanAllRUV task limit is not enforced for
|
||||||
|
replicated tasks
|
||||||
|
|
||||||
|
Bug Description:
|
||||||
|
|
||||||
|
There is a hard limit of 64 concurrent cleanAllRUV tasks, but this limit is
|
||||||
|
only enforced when creating "new" tasks. It was not enforced when a task was
|
||||||
|
received via an extended operation. There were also race conditions in the
|
||||||
|
existing logic that allowed the array of cleaned rids to get corrupted . This
|
||||||
|
allowed for a very large number of task threads to be created.
|
||||||
|
|
||||||
|
Fix Description:
|
||||||
|
|
||||||
|
Maintain a new counter to keep track of the number of clean and abort threads
|
||||||
|
to make sure it never over runs the rid array buffers.
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/50538
|
||||||
|
|
||||||
|
Reviewed by: lkrispenz(Thanks!)
|
||||||
|
---
|
||||||
|
.../suites/replication/cleanallruv_test.py | 47 +++-
|
||||||
|
ldap/servers/plugins/replication/repl5.h | 7 +-
|
||||||
|
.../replication/repl5_replica_config.c | 247 ++++++++++--------
|
||||||
|
ldap/servers/plugins/replication/repl_extop.c | 19 +-
|
||||||
|
4 files changed, 202 insertions(+), 118 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
index 620a53e1a..43801dd52 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2019 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -7,7 +7,6 @@
|
||||||
|
# --- END COPYRIGHT BLOCK ---
|
||||||
|
#
|
||||||
|
import threading
|
||||||
|
-
|
||||||
|
import pytest
|
||||||
|
from lib389.tasks import *
|
||||||
|
from lib389.utils import *
|
||||||
|
@@ -859,6 +858,50 @@ def test_multiple_tasks_with_force(topology_m4):
|
||||||
|
restore_master4(topology_m4)
|
||||||
|
|
||||||
|
|
||||||
|
+def test_max_tasks(topology_m4):
|
||||||
|
+ """Test we can not create more than 64 cleaning tasks
|
||||||
|
+
|
||||||
|
+ :id: c34d0b40-3c3e-4f53-8656-5e4c2a310a1f
|
||||||
|
+ :setup: Replication setup with four masters
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Stop masters 3 & 4
|
||||||
|
+ 2. Create over 64 tasks between m1 and m2
|
||||||
|
+ 3. Check logs to see if (>65) tasks were rejected
|
||||||
|
+
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. Success
|
||||||
|
+ 3. Success
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ # Stop masters 3 & 4
|
||||||
|
+ m1 = topology_m4.ms["master1"]
|
||||||
|
+ m2 = topology_m4.ms["master2"]
|
||||||
|
+ m3 = topology_m4.ms["master3"]
|
||||||
|
+ m4 = topology_m4.ms["master4"]
|
||||||
|
+ m3.stop()
|
||||||
|
+ m4.stop()
|
||||||
|
+
|
||||||
|
+ # Add over 64 tasks between master1 & 2 to try to exceed the 64 task limit
|
||||||
|
+ for i in range(1, 64):
|
||||||
|
+ cruv_task = CleanAllRUVTask(m1)
|
||||||
|
+ cruv_task.create(properties={
|
||||||
|
+ 'replica-id': str(i),
|
||||||
|
+ 'replica-base-dn': DEFAULT_SUFFIX,
|
||||||
|
+ 'replica-force-cleaning': 'no', # This forces these tasks to stick around
|
||||||
|
+ })
|
||||||
|
+ cruv_task = CleanAllRUVTask(m2)
|
||||||
|
+ cruv_task.create(properties={
|
||||||
|
+ 'replica-id': "10" + str(i),
|
||||||
|
+ 'replica-base-dn': DEFAULT_SUFFIX,
|
||||||
|
+ 'replica-force-cleaning': 'yes', # This allows the tasks to propagate
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ # Check the errors log for our error message in master 1
|
||||||
|
+ assert m1.searchErrorsLog('Exceeded maximum number of active CLEANALLRUV tasks')
|
||||||
|
+>>>>>>> ab24aa4cb... Issue 50538 - cleanAllRUV task limit is not enforced for replicated tasks
|
||||||
|
+
|
||||||
|
+
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Run isolated
|
||||||
|
# -s for DEBUG mode
|
||||||
|
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||||
|
index 3c7f06f36..b06c6fbf4 100644
|
||||||
|
--- a/ldap/servers/plugins/replication/repl5.h
|
||||||
|
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||||
|
@@ -80,6 +80,8 @@
|
||||||
|
#define CLEANRUV_FINISHED "finished"
|
||||||
|
#define CLEANRUV_CLEANING "cleaning"
|
||||||
|
#define CLEANRUV_NO_MAXCSN "no maxcsn"
|
||||||
|
+#define CLEANALLRUV_ID "CleanAllRUV Task"
|
||||||
|
+#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task"
|
||||||
|
|
||||||
|
/* DS 5.0 replication protocol error codes */
|
||||||
|
#define NSDS50_REPL_REPLICA_READY 0x00 /* Replica ready, go ahead */
|
||||||
|
@@ -784,6 +786,7 @@ void multimaster_mtnode_construct_replicas(void);
|
||||||
|
void multimaster_be_state_change(void *handle, char *be_name, int old_be_state, int new_be_state);
|
||||||
|
|
||||||
|
#define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */
|
||||||
|
+#define CLEANRID_BUFSIZ 128
|
||||||
|
|
||||||
|
typedef struct _cleanruv_data
|
||||||
|
{
|
||||||
|
@@ -815,6 +818,8 @@ int get_replica_type(Replica *r);
|
||||||
|
int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid);
|
||||||
|
void add_cleaned_rid(cleanruv_data *data, char *maxcsn);
|
||||||
|
int is_cleaned_rid(ReplicaId rid);
|
||||||
|
+int32_t check_and_set_cleanruv_task_count(ReplicaId rid);
|
||||||
|
+int32_t check_and_set_abort_cleanruv_task_count(void);
|
||||||
|
int replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
|
||||||
|
void replica_cleanallruv_thread_ext(void *arg);
|
||||||
|
void stop_ruv_cleaning(void);
|
||||||
|
@@ -833,8 +838,6 @@ void set_cleaned_rid(ReplicaId rid);
|
||||||
|
void cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...);
|
||||||
|
char *replica_cleanallruv_get_local_maxcsn(ReplicaId rid, char *base_dn);
|
||||||
|
|
||||||
|
-
|
||||||
|
-
|
||||||
|
/* replutil.c */
|
||||||
|
LDAPControl *create_managedsait_control(void);
|
||||||
|
LDAPControl *create_backend_control(Slapi_DN *sdn);
|
||||||
|
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||||
|
index 62bfcf6ce..80a079784 100644
|
||||||
|
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||||
|
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||||
|
@@ -30,17 +30,18 @@
|
||||||
|
#define CLEANALLRUV "CLEANALLRUV"
|
||||||
|
#define CLEANALLRUVLEN 11
|
||||||
|
#define REPLICA_RDN "cn=replica"
|
||||||
|
-#define CLEANALLRUV_ID "CleanAllRUV Task"
|
||||||
|
-#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task"
|
||||||
|
|
||||||
|
int slapi_log_urp = SLAPI_LOG_REPL;
|
||||||
|
-static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0};
|
||||||
|
-static ReplicaId pre_cleaned_rids[CLEANRIDSIZ + 1] = {0};
|
||||||
|
-static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0};
|
||||||
|
-static Slapi_RWLock *rid_lock = NULL;
|
||||||
|
-static Slapi_RWLock *abort_rid_lock = NULL;
|
||||||
|
+static ReplicaId cleaned_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+static ReplicaId pre_cleaned_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+static ReplicaId aborted_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+static PRLock *rid_lock = NULL;
|
||||||
|
+static PRLock *abort_rid_lock = NULL;
|
||||||
|
static PRLock *notify_lock = NULL;
|
||||||
|
static PRCondVar *notify_cvar = NULL;
|
||||||
|
+static PRLock *task_count_lock = NULL;
|
||||||
|
+static int32_t clean_task_count = 0;
|
||||||
|
+static int32_t abort_task_count = 0;
|
||||||
|
|
||||||
|
/* Forward Declartions */
|
||||||
|
static int replica_config_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg);
|
||||||
|
@@ -67,8 +68,6 @@ static int replica_cleanallruv_send_abort_extop(Repl_Agmt *ra, Slapi_Task *task,
|
||||||
|
static int replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *basedn, char *rid_text, char *maxcsn, Slapi_Task *task);
|
||||||
|
static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt);
|
||||||
|
static int replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *ra, char *rid_text, Slapi_Task *task, char *force);
|
||||||
|
-static int get_cleanruv_task_count(void);
|
||||||
|
-static int get_abort_cleanruv_task_count(void);
|
||||||
|
static int replica_cleanup_task(Object *r, const char *task_name, char *returntext, int apply_mods);
|
||||||
|
static int replica_task_done(Replica *replica);
|
||||||
|
static void delete_cleaned_rid_config(cleanruv_data *data);
|
||||||
|
@@ -114,20 +113,27 @@ replica_config_init()
|
||||||
|
PR_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- rid_lock = slapi_new_rwlock();
|
||||||
|
+ rid_lock = PR_NewLock();
|
||||||
|
if (rid_lock == NULL) {
|
||||||
|
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
|
||||||
|
"Failed to create rid_lock; NSPR error - %d\n",
|
||||||
|
PR_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- abort_rid_lock = slapi_new_rwlock();
|
||||||
|
+ abort_rid_lock = PR_NewLock();
|
||||||
|
if (abort_rid_lock == NULL) {
|
||||||
|
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
|
||||||
|
"Failed to create abort_rid_lock; NSPR error - %d\n",
|
||||||
|
PR_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
+ task_count_lock = PR_NewLock();
|
||||||
|
+ if (task_count_lock == NULL) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
|
||||||
|
+ "Failed to create task_count_lock; NSPR error - %d\n",
|
||||||
|
+ PR_GetError());
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
if ((notify_lock = PR_NewLock()) == NULL) {
|
||||||
|
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
|
||||||
|
"Failed to create notify lock; NSPR error - %d\n",
|
||||||
|
@@ -1483,12 +1489,6 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
|
||||||
|
|
||||||
|
cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Initiating CleanAllRUV Task...");
|
||||||
|
|
||||||
|
- if (get_cleanruv_task_count() >= CLEANRIDSIZ) {
|
||||||
|
- /* we are already running the maximum number of tasks */
|
||||||
|
- cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
|
||||||
|
- "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
|
||||||
|
- return LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
- }
|
||||||
|
/*
|
||||||
|
* Grab the replica
|
||||||
|
*/
|
||||||
|
@@ -1540,6 +1540,13 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (check_and_set_cleanruv_task_count(rid) != LDAP_SUCCESS) {
|
||||||
|
+ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
|
||||||
|
+ "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
|
||||||
|
+ rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Launch the cleanallruv thread. Once all the replicas are cleaned it will release the rid
|
||||||
|
*/
|
||||||
|
@@ -1547,6 +1554,9 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
|
||||||
|
if (data == NULL) {
|
||||||
|
cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Failed to allocate cleanruv_data. Aborting task.");
|
||||||
|
rc = -1;
|
||||||
|
+ PR_Lock(task_count_lock);
|
||||||
|
+ clean_task_count--;
|
||||||
|
+ PR_Unlock(task_count_lock);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
data->repl_obj = r;
|
||||||
|
@@ -1629,13 +1639,13 @@ replica_cleanallruv_thread(void *arg)
|
||||||
|
int aborted = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
- if (!data || slapi_is_shutting_down()) {
|
||||||
|
- return; /* no data */
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* Increase active thread count to prevent a race condition at server shutdown */
|
||||||
|
g_incr_active_threadcnt();
|
||||||
|
|
||||||
|
+ if (!data || slapi_is_shutting_down()) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (data->task) {
|
||||||
|
slapi_task_inc_refcount(data->task);
|
||||||
|
slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name,
|
||||||
|
@@ -1682,16 +1692,13 @@ replica_cleanallruv_thread(void *arg)
|
||||||
|
slapi_task_begin(data->task, 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
- * Presetting the rid prevents duplicate thread creation, but allows the db and changelog to still
|
||||||
|
- * process updates from the rid.
|
||||||
|
- * set_cleaned_rid() blocks updates, so we don't want to do that... yet unless we are in force mode.
|
||||||
|
- * If we are forcing a clean independent of state of other servers for this RID we can set_cleaned_rid()
|
||||||
|
+ * We have already preset this rid, but if we are forcing a clean independent of state
|
||||||
|
+ * of other servers for this RID we can set_cleaned_rid()
|
||||||
|
*/
|
||||||
|
if (data->force) {
|
||||||
|
set_cleaned_rid(data->rid);
|
||||||
|
- } else {
|
||||||
|
- preset_cleaned_rid(data->rid);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
rid_text = slapi_ch_smprintf("%d", data->rid);
|
||||||
|
csn_as_string(data->maxcsn, PR_FALSE, csnstr);
|
||||||
|
/*
|
||||||
|
@@ -1861,6 +1868,9 @@ done:
|
||||||
|
/*
|
||||||
|
* If the replicas are cleaned, release the rid
|
||||||
|
*/
|
||||||
|
+ if (slapi_is_shutting_down()) {
|
||||||
|
+ stop_ruv_cleaning();
|
||||||
|
+ }
|
||||||
|
if (!aborted && !slapi_is_shutting_down()) {
|
||||||
|
/*
|
||||||
|
* Success - the rid has been cleaned!
|
||||||
|
@@ -1879,10 +1889,9 @@ done:
|
||||||
|
} else {
|
||||||
|
cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Propagated task does not delete Keep alive entry (%d).", data->rid);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
clean_agmts(data);
|
||||||
|
remove_cleaned_rid(data->rid);
|
||||||
|
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d).", data->rid);
|
||||||
|
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d)", data->rid);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Shutdown or abort
|
||||||
|
@@ -1915,6 +1924,10 @@ done:
|
||||||
|
slapi_ch_free_string(&data->force);
|
||||||
|
slapi_ch_free_string(&rid_text);
|
||||||
|
slapi_ch_free((void **)&data);
|
||||||
|
+ /* decrement task count */
|
||||||
|
+ PR_Lock(task_count_lock);
|
||||||
|
+ clean_task_count--;
|
||||||
|
+ PR_Unlock(task_count_lock);
|
||||||
|
g_decr_active_threadcnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2414,16 +2427,14 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, cleanruv_data *clean_data)
|
||||||
|
int
|
||||||
|
is_cleaned_rid(ReplicaId rid)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- slapi_rwlock_rdlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != 0; i++) {
|
||||||
|
+ PR_Lock(rid_lock);
|
||||||
|
+ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
if (rid == cleaned_rids[i]) {
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2431,16 +2442,14 @@ is_cleaned_rid(ReplicaId rid)
|
||||||
|
int
|
||||||
|
is_pre_cleaned_rid(ReplicaId rid)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- slapi_rwlock_rdlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != 0; i++) {
|
||||||
|
+ PR_Lock(rid_lock);
|
||||||
|
+ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
if (rid == pre_cleaned_rids[i]) {
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2453,14 +2462,14 @@ is_task_aborted(ReplicaId rid)
|
||||||
|
if (rid == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- slapi_rwlock_rdlock(abort_rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != 0; i++) {
|
||||||
|
+ PR_Lock(abort_rid_lock);
|
||||||
|
+ for (i = 0; i < CLEANRID_BUFSIZ && aborted_rids[i] != 0; i++) {
|
||||||
|
if (rid == aborted_rids[i]) {
|
||||||
|
- slapi_rwlock_unlock(abort_rid_lock);
|
||||||
|
+ PR_Unlock(abort_rid_lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(abort_rid_lock);
|
||||||
|
+ PR_Unlock(abort_rid_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2469,15 +2478,14 @@ preset_cleaned_rid(ReplicaId rid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- slapi_rwlock_wrlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ; i++) {
|
||||||
|
+ PR_Lock(rid_lock);
|
||||||
|
+ for (i = 0; i < CLEANRID_BUFSIZ && pre_cleaned_rids[i] != rid; i++) {
|
||||||
|
if (pre_cleaned_rids[i] == 0) {
|
||||||
|
pre_cleaned_rids[i] = rid;
|
||||||
|
- pre_cleaned_rids[i + 1] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2490,14 +2498,13 @@ set_cleaned_rid(ReplicaId rid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- slapi_rwlock_wrlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ; i++) {
|
||||||
|
+ PR_Lock(rid_lock);
|
||||||
|
+ for (i = 0; i < CLEANRID_BUFSIZ && cleaned_rids[i] != rid; i++) {
|
||||||
|
if (cleaned_rids[i] == 0) {
|
||||||
|
cleaned_rids[i] = rid;
|
||||||
|
- cleaned_rids[i + 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2569,15 +2576,14 @@ add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root)
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- slapi_rwlock_wrlock(abort_rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ; i++) {
|
||||||
|
+ PR_Lock(abort_rid_lock);
|
||||||
|
+ for (i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
if (aborted_rids[i] == 0) {
|
||||||
|
aborted_rids[i] = rid;
|
||||||
|
- aborted_rids[i + 1] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(abort_rid_lock);
|
||||||
|
+ PR_Unlock(abort_rid_lock);
|
||||||
|
/*
|
||||||
|
* Write the rid to the config entry
|
||||||
|
*/
|
||||||
|
@@ -2620,21 +2626,24 @@ delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root, int skip)
|
||||||
|
char *data;
|
||||||
|
char *dn;
|
||||||
|
int rc;
|
||||||
|
- int i;
|
||||||
|
|
||||||
|
if (r == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (skip) {
|
||||||
|
/* skip the deleting of the config, and just remove the in memory rid */
|
||||||
|
- slapi_rwlock_wrlock(abort_rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != rid; i++)
|
||||||
|
- ; /* found rid, stop */
|
||||||
|
- for (; i < CLEANRIDSIZ; i++) {
|
||||||
|
- /* rewrite entire array */
|
||||||
|
- aborted_rids[i] = aborted_rids[i + 1];
|
||||||
|
- }
|
||||||
|
- slapi_rwlock_unlock(abort_rid_lock);
|
||||||
|
+ ReplicaId new_abort_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+ int32_t idx = 0;
|
||||||
|
+
|
||||||
|
+ PR_Lock(abort_rid_lock);
|
||||||
|
+ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
+ if (aborted_rids[i] != rid) {
|
||||||
|
+ new_abort_rids[idx] = aborted_rids[i];
|
||||||
|
+ idx++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ memcpy(aborted_rids, new_abort_rids, sizeof(new_abort_rids));
|
||||||
|
+ PR_Unlock(abort_rid_lock);
|
||||||
|
} else {
|
||||||
|
/* only remove the config, leave the in-memory rid */
|
||||||
|
dn = replica_get_dn(r);
|
||||||
|
@@ -2792,27 +2801,31 @@ bail:
|
||||||
|
void
|
||||||
|
remove_cleaned_rid(ReplicaId rid)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
- /*
|
||||||
|
- * Remove this rid, and optimize the array
|
||||||
|
- */
|
||||||
|
- slapi_rwlock_wrlock(rid_lock);
|
||||||
|
+ ReplicaId new_cleaned_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+ ReplicaId new_pre_cleaned_rids[CLEANRID_BUFSIZ] = {0};
|
||||||
|
+ size_t idx = 0;
|
||||||
|
+
|
||||||
|
+ PR_Lock(rid_lock);
|
||||||
|
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++)
|
||||||
|
- ; /* found rid, stop */
|
||||||
|
- for (; i < CLEANRIDSIZ; i++) {
|
||||||
|
- /* rewrite entire array */
|
||||||
|
- cleaned_rids[i] = cleaned_rids[i + 1];
|
||||||
|
+ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
+ if (cleaned_rids[i] != rid) {
|
||||||
|
+ new_cleaned_rids[idx] = cleaned_rids[i];
|
||||||
|
+ idx++;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ memcpy(cleaned_rids, new_cleaned_rids, sizeof(new_cleaned_rids));
|
||||||
|
+
|
||||||
|
/* now do the preset cleaned rids */
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != rid; i++)
|
||||||
|
- ; /* found rid, stop */
|
||||||
|
- for (; i < CLEANRIDSIZ; i++) {
|
||||||
|
- /* rewrite entire array */
|
||||||
|
- pre_cleaned_rids[i] = pre_cleaned_rids[i + 1];
|
||||||
|
+ idx = 0;
|
||||||
|
+ for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
|
||||||
|
+ if (pre_cleaned_rids[i] != rid) {
|
||||||
|
+ new_pre_cleaned_rids[idx] = pre_cleaned_rids[i];
|
||||||
|
+ idx++;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+ memcpy(pre_cleaned_rids, new_pre_cleaned_rids, sizeof(new_pre_cleaned_rids));
|
||||||
|
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(rid_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2840,16 +2853,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)),
|
||||||
|
char *ridstr = NULL;
|
||||||
|
int rc = SLAPI_DSE_CALLBACK_OK;
|
||||||
|
|
||||||
|
- if (get_abort_cleanruv_task_count() >= CLEANRIDSIZ) {
|
||||||
|
- /* we are already running the maximum number of tasks */
|
||||||
|
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||||
|
- "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",
|
||||||
|
- CLEANRIDSIZ);
|
||||||
|
- cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext);
|
||||||
|
- *returncode = LDAP_OPERATIONS_ERROR;
|
||||||
|
- return SLAPI_DSE_CALLBACK_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* allocate new task now */
|
||||||
|
task = slapi_new_task(slapi_entry_get_ndn(e));
|
||||||
|
|
||||||
|
@@ -2934,6 +2937,16 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)),
|
||||||
|
*/
|
||||||
|
certify_all = "no";
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) {
|
||||||
|
+ /* we are already running the maximum number of tasks */
|
||||||
|
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||||
|
+ "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",
|
||||||
|
+ CLEANRIDSIZ);
|
||||||
|
+ cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext);
|
||||||
|
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
/*
|
||||||
|
* Create payload
|
||||||
|
*/
|
||||||
|
@@ -3142,6 +3155,9 @@ done:
|
||||||
|
slapi_ch_free_string(&data->certify);
|
||||||
|
slapi_sdn_free(&data->sdn);
|
||||||
|
slapi_ch_free((void **)&data);
|
||||||
|
+ PR_Lock(task_count_lock);
|
||||||
|
+ abort_task_count--;
|
||||||
|
+ PR_Unlock(task_count_lock);
|
||||||
|
g_decr_active_threadcnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3493,36 +3509,43 @@ replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *agmt, char *rid_text,
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-get_cleanruv_task_count(void)
|
||||||
|
+/*
|
||||||
|
+ * Before starting a cleanAllRUV task make sure there are not
|
||||||
|
+ * too many task threads already running. If everything is okay
|
||||||
|
+ * also pre-set the RID now so rebounding extended ops do not
|
||||||
|
+ * try to clean it over and over.
|
||||||
|
+ */
|
||||||
|
+int32_t
|
||||||
|
+check_and_set_cleanruv_task_count(ReplicaId rid)
|
||||||
|
{
|
||||||
|
- int i, count = 0;
|
||||||
|
+ int32_t rc = 0;
|
||||||
|
|
||||||
|
- slapi_rwlock_wrlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ; i++) {
|
||||||
|
- if (pre_cleaned_rids[i] != 0) {
|
||||||
|
- count++;
|
||||||
|
- }
|
||||||
|
+ PR_Lock(task_count_lock);
|
||||||
|
+ if (clean_task_count >= CLEANRIDSIZ) {
|
||||||
|
+ rc = -1;
|
||||||
|
+ } else {
|
||||||
|
+ clean_task_count++;
|
||||||
|
+ preset_cleaned_rid(rid);
|
||||||
|
}
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(task_count_lock);
|
||||||
|
|
||||||
|
- return count;
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-get_abort_cleanruv_task_count(void)
|
||||||
|
+int32_t
|
||||||
|
+check_and_set_abort_cleanruv_task_count(void)
|
||||||
|
{
|
||||||
|
- int i, count = 0;
|
||||||
|
+ int32_t rc = 0;
|
||||||
|
|
||||||
|
- slapi_rwlock_wrlock(rid_lock);
|
||||||
|
- for (i = 0; i < CLEANRIDSIZ; i++) {
|
||||||
|
- if (aborted_rids[i] != 0) {
|
||||||
|
- count++;
|
||||||
|
+ PR_Lock(task_count_lock);
|
||||||
|
+ if (abort_task_count > CLEANRIDSIZ) {
|
||||||
|
+ rc = -1;
|
||||||
|
+ } else {
|
||||||
|
+ abort_task_count++;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
- slapi_rwlock_unlock(rid_lock);
|
||||||
|
+ PR_Unlock(task_count_lock);
|
||||||
|
|
||||||
|
- return count;
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
||||||
|
index 68e2544b4..0c2abb6d5 100644
|
||||||
|
--- a/ldap/servers/plugins/replication/repl_extop.c
|
||||||
|
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
||||||
|
@@ -1393,6 +1393,12 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
|
||||||
|
rc = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
+ if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) {
|
||||||
|
+ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
|
||||||
|
+ "Exceeded maximum number of active abort CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
|
||||||
|
+ rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
/*
|
||||||
|
* Prepare the abort data
|
||||||
|
*/
|
||||||
|
@@ -1499,6 +1505,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
|
||||||
|
if (force == NULL) {
|
||||||
|
force = "no";
|
||||||
|
}
|
||||||
|
+
|
||||||
|
maxcsn = csn_new();
|
||||||
|
csn_init_by_string(maxcsn, csnstr);
|
||||||
|
/*
|
||||||
|
@@ -1535,13 +1542,21 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
|
||||||
|
goto free_and_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (check_and_set_cleanruv_task_count((ReplicaId)rid) != LDAP_SUCCESS) {
|
||||||
|
+ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
|
||||||
|
+ "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
|
||||||
|
+ rc = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
+ goto free_and_return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (replica_get_type(r) != REPLICA_TYPE_READONLY) {
|
||||||
|
/*
|
||||||
|
* Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
|
||||||
|
*
|
||||||
|
* This will also release mtnode_ext->replica
|
||||||
|
*/
|
||||||
|
- slapi_log_err(SLAPI_LOG_INFO, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Launching cleanAllRUV thread...\n");
|
||||||
|
+
|
||||||
|
+ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...\n");
|
||||||
|
data = (cleanruv_data *)slapi_ch_calloc(1, sizeof(cleanruv_data));
|
||||||
|
if (data == NULL) {
|
||||||
|
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Failed to allocate "
|
||||||
|
@@ -1635,7 +1650,7 @@ free_and_return:
|
||||||
|
ber_printf(resp_bere, "{s}", CLEANRUV_ACCEPTED);
|
||||||
|
ber_flatten(resp_bere, &resp_bval);
|
||||||
|
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
|
||||||
|
- slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
|
||||||
|
+ slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL);
|
||||||
|
/* resp_bere */
|
||||||
|
if (NULL != resp_bere) {
|
||||||
|
ber_free(resp_bere, 1);
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
From f50dfbb61224e6a9516b93cd3d3957c1fde4798e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Thu, 22 Aug 2019 10:26:24 -0400
|
||||||
|
Subject: [PATCH] Issue 49624 - modrdn silently fails if DB deadlock occurs
|
||||||
|
|
||||||
|
Bug Description:
|
||||||
|
|
||||||
|
If a DB Deadlock error occurs during a modrdn operation the entry
|
||||||
|
cache gets updated (corrupted), but the update is not applied to
|
||||||
|
the database.
|
||||||
|
|
||||||
|
Fix Description:
|
||||||
|
|
||||||
|
Looks like there was a copy & paste error, and the wrong attribute
|
||||||
|
was updated during the retry of the modrdn operation.
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/49624
|
||||||
|
|
||||||
|
Reviewed by: lkrispenz (Thanks!)
|
||||||
|
---
|
||||||
|
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||||
|
index 65610d613..433ed88fb 100644
|
||||||
|
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||||
|
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||||
|
@@ -251,7 +251,7 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
|
||||||
|
slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &dn_newsuperiordn);
|
||||||
|
slapi_sdn_free(&dn_newsuperiordn);
|
||||||
|
slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
|
||||||
|
- orig_dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
|
||||||
|
+ dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
|
||||||
|
/* must duplicate ec before returning it to cache,
|
||||||
|
* which could free the entry. */
|
||||||
|
if ((tmpentry = backentry_dup(original_entry ? original_entry : ec)) == NULL) {
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
From d8935139d377ad75be4242db7d3194f3706dc44a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Pichugin <spichugi@redhat.com>
|
||||||
|
Date: Thu, 29 Aug 2019 15:51:56 +0200
|
||||||
|
Subject: [PATCH] Issue 50572 - After running cl-dump dbdir/cldb/*ldif.done are
|
||||||
|
not deleted
|
||||||
|
|
||||||
|
Description: By default, remove ldif.done files after running cl-dump.
|
||||||
|
Add an option '-l' which allows keep the files.
|
||||||
|
Update man files.
|
||||||
|
|
||||||
|
https://pagure.io/389-ds-base/issue/50572
|
||||||
|
|
||||||
|
Reviewed by: firstyear, mreynolds (Thanks!)
|
||||||
|
---
|
||||||
|
ldap/admin/src/scripts/cl-dump.pl | 23 +++++++++++++++--------
|
||||||
|
man/man1/cl-dump.1 | 11 +++++++----
|
||||||
|
2 files changed, 22 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/admin/src/scripts/cl-dump.pl b/ldap/admin/src/scripts/cl-dump.pl
|
||||||
|
index f4ad5dd33..2e7f20413 100755
|
||||||
|
--- a/ldap/admin/src/scripts/cl-dump.pl
|
||||||
|
+++ b/ldap/admin/src/scripts/cl-dump.pl
|
||||||
|
@@ -5,7 +5,7 @@
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
-# See LICENSE for details.
|
||||||
|
+# See LICENSE for details.
|
||||||
|
# END COPYRIGHT BLOCK
|
||||||
|
###################################################################################
|
||||||
|
#
|
||||||
|
@@ -13,7 +13,7 @@
|
||||||
|
#
|
||||||
|
# SYNOPSIS:
|
||||||
|
# cl-dump.pl [-h host] [-p port] [-D bind-dn] -w bind-password | -P bind-cert
|
||||||
|
-# [-r replica-roots] [-o output-file] [-c] [-v]
|
||||||
|
+# [-r replica-roots] [-o output-file] [-c] [-l] [-v]
|
||||||
|
#
|
||||||
|
# cl-dump.pl -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]
|
||||||
|
#
|
||||||
|
@@ -22,7 +22,7 @@
|
||||||
|
#
|
||||||
|
# OPTIONS:
|
||||||
|
# -c Dump and interpret CSN only. This option can be used with or
|
||||||
|
-# without -i option.
|
||||||
|
+# without -i option.
|
||||||
|
#
|
||||||
|
# -D bind-dn
|
||||||
|
# Directory server's bind DN. Default to "cn=Directory Manager" if
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
# Directory server's host. Default to the server where the script
|
||||||
|
# is running.
|
||||||
|
#
|
||||||
|
+# -l Preserve generated ldif.done files from changelogdir
|
||||||
|
+#
|
||||||
|
# -i changelog-ldif-file-with-base64encoding
|
||||||
|
# If you already have a ldif-like changelog, but the changes
|
||||||
|
# in that file are encoded, you may use this option to
|
||||||
|
@@ -68,7 +70,7 @@
|
||||||
|
# all of this nonsense can be omitted if the mozldapsdk and perldap are
|
||||||
|
# installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5)
|
||||||
|
|
||||||
|
-$usage="Usage: $0 [-h host] [-p port] [-D bind-dn] [-w bind-password | -P bind-cert] [-r replica-roots] [-o output-file] [-c] [-v]\n\n $0 -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]\n";
|
||||||
|
+$usage="Usage: $0 [-h host] [-p port] [-D bind-dn] [-w bind-password | -P bind-cert] [-r replica-roots] [-o output-file] [-c] [-l] [-v]\n\n $0 -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]\n";
|
||||||
|
|
||||||
|
use Getopt::Std; # Parse command line arguments
|
||||||
|
use Mozilla::LDAP::Conn; # LDAP module for Perl
|
||||||
|
@@ -86,7 +88,7 @@ $version = "Directory Server Changelog Dump - Version 1.0";
|
||||||
|
$| = 1;
|
||||||
|
|
||||||
|
# Check for legal options
|
||||||
|
- if (!getopts('h:p:D:w:P:r:o:cvi:')) {
|
||||||
|
+ if (!getopts('h:p:D:w:P:r:o:clvi:')) {
|
||||||
|
print $usage;
|
||||||
|
exit -1;
|
||||||
|
}
|
||||||
|
@@ -123,7 +125,7 @@ sub validateArgs
|
||||||
|
if ($opt_o && ! open (OUTPUT, ">$opt_o")) {
|
||||||
|
print "Can't create output file $opt_o\n";
|
||||||
|
$rc = -1;
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
# Open STDOUT if option -o is missing
|
||||||
|
open (OUTPUT, ">-") if !$opt_o;
|
||||||
|
|
||||||
|
@@ -194,10 +196,15 @@ sub cl_dump_and_decode
|
||||||
|
else {
|
||||||
|
&cl_decode ($_);
|
||||||
|
}
|
||||||
|
- # Test op -M doesn't work well so we use rename
|
||||||
|
+ # Test op -M doesn't work well so we use rename/remove
|
||||||
|
# here to avoid reading the same ldif file more
|
||||||
|
# than once.
|
||||||
|
- rename ($ldif, "$ldif.done");
|
||||||
|
+ if ($opt_l) {
|
||||||
|
+ rename ($ldif, "$ldif.done");
|
||||||
|
+ } else {
|
||||||
|
+ # Remove the file - default behaviou when '-l' is not specified
|
||||||
|
+ unlink ($ldif)
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
&print_header ($replica, "Not Found") if !$gotldif;
|
||||||
|
}
|
||||||
|
diff --git a/man/man1/cl-dump.1 b/man/man1/cl-dump.1
|
||||||
|
index db736aca9..fbb836a72 100644
|
||||||
|
--- a/man/man1/cl-dump.1
|
||||||
|
+++ b/man/man1/cl-dump.1
|
||||||
|
@@ -20,7 +20,7 @@ cl-dump \- Dump and decode Directory Server replication change log
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B cl\-dump
|
||||||
|
[\fI\-h host\fR] [\fI\-p port\fR] [\fI\-D bind\(hydn\fR] \-w bind\(hypassword | \-P bind\(hycert
|
||||||
|
- [\fI\-r replica\(hyroots\fR] [\fI\-o output\(hyfile\fR] [\fI\-c\fR] [\fI\-v\fR]
|
||||||
|
+ [\fI\-r replica\(hyroots\fR] [\fI\-o output\(hyfile\fR] [\fI\-c\fR] [\fI\-l\fR] [\fI\-v\fR]
|
||||||
|
|
||||||
|
.PP
|
||||||
|
.B cl\-dump
|
||||||
|
@@ -30,12 +30,12 @@ cl-dump \- Dump and decode Directory Server replication change log
|
||||||
|
Dump and decode Directory Server replication change log
|
||||||
|
.PP
|
||||||
|
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||||
|
-.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||||
|
+.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||||
|
.\" respectively.
|
||||||
|
.SH OPTIONS
|
||||||
|
A summary of options is included below.
|
||||||
|
.TP
|
||||||
|
-.B \-c
|
||||||
|
+.B \-c
|
||||||
|
Dump and interpret CSN only. This option can be used with or
|
||||||
|
without \-i option.
|
||||||
|
.TP
|
||||||
|
@@ -47,6 +47,9 @@ the option is omitted.
|
||||||
|
Directory server's host. Default to the server where the script
|
||||||
|
is running.
|
||||||
|
.TP
|
||||||
|
+.B \-l
|
||||||
|
+Preserve generated ldif.done files from changelogdir
|
||||||
|
+.TP
|
||||||
|
.B \-i changelog\(hyldif\(hyfile\(hywith\(hybase64encoding
|
||||||
|
If you already have a ldif-like changelog, but the changes
|
||||||
|
in that file are encoded, you may use this option to
|
||||||
|
@@ -66,7 +69,7 @@ Specify replica roots whose changelog you want to dump. The replica
|
||||||
|
roots may be separated by comma. All the replica roots would be
|
||||||
|
dumped if the option is omitted.
|
||||||
|
.TP
|
||||||
|
-.B \-v
|
||||||
|
+.B \-v
|
||||||
|
Print the version of this script.
|
||||||
|
.TP
|
||||||
|
.B \-w bind\(hypassword
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
27
SOURCES/0007-Issue-50538-Fix-cherry-pick-error.patch
Normal file
27
SOURCES/0007-Issue-50538-Fix-cherry-pick-error.patch
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
From 5fee4d79db94684d8093501fde3422ad34ac2716 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Tue, 3 Sep 2019 13:40:27 -0400
|
||||||
|
Subject: [PATCH] Issue 50538 - Fix cherry-pick error
|
||||||
|
|
||||||
|
Description: Remove cherry-=pick error formating
|
||||||
|
|
||||||
|
relates: https://pagure.io/389-ds-base/issue/50538
|
||||||
|
---
|
||||||
|
dirsrvtests/tests/suites/replication/cleanallruv_test.py | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
index 43801dd52..caf214b19 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
|
||||||
|
@@ -899,7 +899,6 @@ def test_max_tasks(topology_m4):
|
||||||
|
|
||||||
|
# Check the errors log for our error message in master 1
|
||||||
|
assert m1.searchErrorsLog('Exceeded maximum number of active CLEANALLRUV tasks')
|
||||||
|
->>>>>>> ab24aa4cb... Issue 50538 - cleanAllRUV task limit is not enforced for replicated tasks
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
4
SOURCES/389-ds-base-devel.README
Normal file
4
SOURCES/389-ds-base-devel.README
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
For detailed information on developing plugins for
|
||||||
|
389 Directory Server visit.
|
||||||
|
|
||||||
|
http://port389/wiki/Plugins
|
16
SOURCES/389-ds-base-git.sh
Normal file
16
SOURCES/389-ds-base-git.sh
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DATE=`date +%Y%m%d`
|
||||||
|
# use a real tag name here
|
||||||
|
VERSION=1.3.1.6
|
||||||
|
PKGNAME=389-ds-base
|
||||||
|
TAG=${TAG:-$PKGNAME-$VERSION}
|
||||||
|
URL="http://git.fedorahosted.org/git/?p=389/ds.git;a=snapshot;h=$TAG;sf=tgz"
|
||||||
|
SRCNAME=$PKGNAME-$VERSION
|
||||||
|
|
||||||
|
wget -O $SRCNAME.tar.gz "$URL"
|
||||||
|
|
||||||
|
echo convert tgz format to tar.bz2 format
|
||||||
|
|
||||||
|
gunzip $PKGNAME-$VERSION.tar.gz
|
||||||
|
bzip2 $PKGNAME-$VERSION.tar
|
3023
SPECS/389-ds-base.spec
Normal file
3023
SPECS/389-ds-base.spec
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue