[Pkg-freeipa-devel] [Git][freeipa-team/389-ds-base][upstream] 18 commits: missing clang formatting in urp_tombstone
Timo Aaltonen
gitlab at salsa.debian.org
Fri Jun 1 09:46:23 BST 2018
Timo Aaltonen pushed to branch upstream at FreeIPA packaging / 389-ds-base
Commits:
81a9d757 by Ludwig Krispenz at 2018-03-08T14:20:05+01:00
missing clang formatting in urp_tombstone
- - - - -
485cf0c6 by Mark Reynolds at 2018-03-16T09:02:36-04:00
Ticket 49599 - Revise replication total init status messages
Description: Previously the replication update status messages were
updated to a more readable format. This should also be
done with the total update status messages.
https://pagure.io/389-ds-base/issue/49599
Reviewed by: lkrispen(Thanks!)
(cherry picked from commit b67f0f822911d0abd4467734a7150c6a94635b82)
- - - - -
d5e2f749 by Thierry Bordaz at 2018-03-23T16:02:11+01:00
Ticket 49619 - adjustment of csn_generator can fail so next generated csn can be equal to the most recent one received
Bug Description:
On consumer side csn_generator ajustment occurs (let CSN = highest known csn)
when a replication session starts
when a csn is generated locally and than csn is <= CSN
During adjustment, in the case
there is no remote/local offset (time change)
the current_time on the consumer is identical to CSN
Then next locally generated csn will only differ with seqnum
The seqnum of the csn_generator is increased only if CSN.seqnum is larger
than the csn_generator one.
In case of egality, it remains unchanged.
The consequence is that the next locally generated csn will be identical to CSN (except for the RID).
So even after csn_generator adjustment, csn_generator may create csn that are not larger than the CSN
Fix Description:
compare the new generated timestamp (time+offsets) with adjustment one.
If the new is greater or EQUAL, make sure the local seqnum is ahead the remote one
https://pagure.io/389-ds-base/issue/49619
Reviewed by: Mark Reynolds
Platforms tested: F27
Flag Day: no
Doc impact: no
- - - - -
65d0e49b by Mark Reynolds at 2018-03-26T12:24:28-04:00
Rebase to 1.3.8
- - - - -
804002e1 by Mark Reynolds at 2018-03-29T13:53:38-04:00
Ticket 48184 - revert previous patch around unuc-stans shutdown crash
https://pagure.io/389-ds-base/issue/48184
- - - - -
acd3a91d by Ludwig Krispenz at 2018-04-05T10:28:19+02:00
Ticket 49631 - same csn generated twice
Bug: if in the csn adjustment the local time was less or equal than the remote time
the sequence number has always been adjusted to remote++
but if the csn time was equal and the local seq number was larger the effect
was a reset of the csn generato.
Fix: correctly handles seqnum in csn adjustment
Reviewed by: Mark, thanks
- - - - -
8505cb8b by Mark Reynolds at 2018-04-20T11:08:45-04:00
Ticket 49644 - crash in debug build
Description: In a debug build of the server it crashes when searching
the cn=config. This is due to a pointer not being initialized
before being dereferenced.
https://pagure.io/389-ds-base/issue/49644
Reviewed by: mreynolds(one line commit rule)
(cherry picked from commit 5bfc18a245405229bd7bd2acfee681e68df338d6)
- - - - -
183bacdd by Mark Reynolds at 2018-04-24T11:02:02-04:00
Ticket 49649 - Use reentrant crypt_r()
Bug Description: We were previously using crypt() which is not
thread safe and reuired a lock. Using pwdhash cli
tool caused a crash because the lock was not created
when invoked by the cli.
Fix Description: Use crypt_r() instead which does not require any locking.
https://pagure.io/389-ds-base/issue/49649
Reviewed by: Simon(Thanks!)
(cherry picked from commit 530a2db1776fca545436cbac2987f6b86f6c7048)
- - - - -
eb08d435 by Mark Reynolds at 2018-04-27T08:59:18-04:00
Ticket 49652 - DENY aci's are not handled properly
Bug Description: There are really two issues here. One, when a resource
is denied by a DENY aci the cached results for that resource
are not proprely set, and on the same connection if the same
operation repeated it will be allowed instead of denied because
the cache result was not proprely updated.
Two, if there are no ALLOW aci's on a resource, then we don't
check the deny rules, and resources that are restricted are
returned to the client.
Fix Description: For issue one, when an entry is denied access reset all the
attributes' cache results to DENIED as it's possible previously
evaluated aci's granted access to some of these attributes which
are still present in the acl result cache.
For issue two, if there are no ALLOW aci's on a resource but
there are DENY aci's, then set the aclpb state flags to
process DENY aci's
https://pagure.io/389-ds-base/issue/49652
Reviewed by: tbordaz & lkrispenz(Thanks!!)
(cherry picked from commit d77c7f0754f67022b42784c05be8a493a00f2ec5)
- - - - -
a5890087 by Mark Reynolds at 2018-05-08T10:54:01-04:00
CVE-2018-1089 - Crash from long search filter
Signed-off-by: Mark Reynolds <mreynolds at redhat.com>
(cherry picked from commit 9d8d096b154e44f3e1fa1f8d5bfe258ed8d9dc51)
- - - - -
2817f0c4 by Mark Reynolds at 2018-05-08T12:35:43-04:00
Ticket 49649
Description: Fix crpyt.h include
https://pagure.io/389-ds-base/issue/49649
Reviewed by: mreynolds(one line commit rule)
- - - - -
90ca2eba by Mark Reynolds at 2018-05-08T12:40:15-04:00
Bump version to 1.3.8.1
- - - - -
b535e288 by Mark Reynolds at 2018-05-10T08:03:56-04:00
Ticket 49665 - Upgrade script doesn't enable PBKDF2 password storage plug-in
Description: There is no upgrade script to add the PBKDF2 plugin, this
fix adds the script.
https://pagure.io/389-ds-base/issue/49665
Reviewed by: ?
(cherry picked from commit dc690dd231a626b3b6a2019fee51e3cb15db7962)
- - - - -
89a9de99 by Mark Reynolds at 2018-05-10T08:04:02-04:00
Ticket 49665 - Upgrade script doesn't enable CRYPT password storage plug-in
Description: There is no upgrade script to add the new CRYPT plugins, this
fix adds the script.
https://pagure.io/389-ds-base/issue/49665
Reviewed by: vashirov(Thanks!)
(cherry picked from commit 91dc832411a1bb6e8bf62bb72c36777ddc63770f)
- - - - -
de9fb252 by Mark Reynolds at 2018-05-13T15:04:08-04:00
Ticket 49671 - Readonly replicas should not write internal ops to changelog
Bug Description: When a hub receives an update that triggers the memberOf
plugin, but that interal operation has no csn and that
causes the update to the changelog to fail and break
replication.
Fix Description: Do not write internal updates with no csns to the changelog
on read-only replicas.
https://pagure.io/389-ds-base/issue/49671
Reviewed by: simon, tbordaz, and lkrispen (Thanks!!!)
(cherry picked from commit afb755bd95f1643665ea34c5a5fa2bb26bfa21b9)
- - - - -
40178b51 by Ludwig Krispenz at 2018-05-17T11:40:45+02:00
Ticket 49696: replicated operations should be serialized
Bug: there was a scenario where two threads could process replication operations in parallel.
The reason was that for a new repl start request the repl conn flag is not set and the
connection is made readable.
When the start repl op is finished, the flagi set, but in a small window the supplier could
already have sent updates and more_data would trigger this thread also to continue to process
repl operations.
Fix: In the situation where a thread successfully processed a start repl request and just set the repl_conn
flag do not use more_data.
Reviewed by: Thierry, thanks
- - - - -
941360ba by Thierry Bordaz at 2018-05-21T14:02:11-04:00
Ticket 48184 - clean up and delete connections at shutdown (2nd try)
Bug description:
During shutdown we would not close connections.
In the past this may have just been an annoyance, but now with the way
nunc-stans works, io events can still trigger on open xeisting connectinos
during shutdown.
Because of NS dynamic it can happen that several jobs wants to work on the
same connection. In such case (a job is already set in c_job) we delay the
new job that will retry.
In addition:
- some call needed c_mutex
- test uninitialized nunc-stans in case of shutdown while startup is not completed
Fix Description: Close connections during shutdown rather than
leaving them alive.
https://pagure.io/389-ds-base/issue/48184
Reviewed by:
Original was Ludwig and Viktor
Second fix reviewed by Mark
Platforms tested: F26
Flag Day: no
Doc impact: no
(cherry picked from commit e562157ca3e97867d902996cc18fb04f90dc10a8)
- - - - -
21800c3c by Mark Reynolds at 2018-05-24T11:46:17-04:00
Bump version to 1.3.8.2
- - - - -
20 changed files:
- Makefile.am
- VERSION.sh
- + dirsrvtests/tests/suites/acl/acl_deny_test.py
- + dirsrvtests/tests/suites/replication/cascading_test.py
- + ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
- + ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
- ldap/servers/plugins/acl/acl.c
- ldap/servers/plugins/pwdstorage/crypt_pwd.c
- ldap/servers/plugins/pwdstorage/pwd_init.c
- ldap/servers/plugins/pwdstorage/pwdstorage.h
- ldap/servers/plugins/replication/repl5_agmt.c
- ldap/servers/plugins/replication/repl5_plugins.c
- ldap/servers/plugins/replication/urp_tombstone.c
- ldap/servers/slapd/back-ldbm/monitor.c
- ldap/servers/slapd/connection.c
- ldap/servers/slapd/csngen.c
- ldap/servers/slapd/daemon.c
- ldap/servers/slapd/filter.c
- ldap/servers/slapd/slap.h
- ldap/servers/slapd/util.c
Changes:
=====================================
Makefile.am
=====================================
--- a/Makefile.am
+++ b/Makefile.am
@@ -952,6 +952,8 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
ldap/admin/src/scripts/50refintprecedence.ldif \
ldap/admin/src/scripts/50retroclprecedence.ldif \
ldap/admin/src/scripts/50rootdnaccesscontrolplugin.ldif \
+ ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif \
+ ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif \
ldap/admin/src/scripts/50contentsync.ldif \
ldap/admin/src/scripts/60upgradeschemafiles.pl \
ldap/admin/src/scripts/60upgradeconfigfiles.pl \
=====================================
VERSION.sh
=====================================
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=3
-VERSION_MAINT=7.10
+VERSION_MAINT=8.2
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
=====================================
dirsrvtests/tests/suites/acl/acl_deny_test.py
=====================================
--- /dev/null
+++ b/dirsrvtests/tests/suites/acl/acl_deny_test.py
@@ -0,0 +1,198 @@
+import logging
+import pytest
+import os
+import ldap
+import time
+from lib389._constants import *
+from lib389.topologies import topology_st as topo
+from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES
+from lib389.idm.domain import Domain
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+ logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+BIND_DN2 = 'uid=tuser,ou=People,dc=example,dc=com'
+BIND_RDN2 = 'tuser'
+BIND_DN = 'uid=tuser1,ou=People,dc=example,dc=com'
+BIND_RDN = 'tuser1'
+SRCH_FILTER = "uid=tuser1"
+SRCH_FILTER2 = "uid=tuser"
+
+aci_list_A = ['(targetattr != "userPassword") (version 3.0; acl "Anonymous access"; allow (read, search, compare)userdn = "ldap:///anyone";)',
+ '(targetattr = "*") (version 3.0;acl "allow tuser";allow (all)(userdn = "ldap:///uid=tuser5,ou=People,dc=example,dc=com");)',
+ '(targetattr != "uid || mail") (version 3.0; acl "deny-attrs"; deny (all) (userdn = "ldap:///anyone");)',
+ '(targetfilter = "(inetUserStatus=1)") ( version 3.0; acl "deny-specific-entry"; deny(all) (userdn = "ldap:///anyone");)']
+
+aci_list_B = ['(targetattr != "userPassword") (version 3.0; acl "Anonymous access"; allow (read, search, compare)userdn = "ldap:///anyone";)',
+ '(targetattr != "uid || mail") (version 3.0; acl "deny-attrs"; deny (all) (userdn = "ldap:///anyone");)',
+ '(targetfilter = "(inetUserStatus=1)") ( version 3.0; acl "deny-specific-entry"; deny(all) (userdn = "ldap:///anyone");)']
+
+
+ at pytest.fixture(scope="module")
+def aci_setup(topo):
+ topo.standalone.log.info("Add {}".format(BIND_DN))
+ user = UserAccount(topo.standalone, BIND_DN)
+ user_props = TEST_USER_PROPERTIES.copy()
+ user_props.update({'sn': BIND_RDN,
+ 'cn': BIND_RDN,
+ 'uid': BIND_RDN,
+ 'inetUserStatus': '1',
+ 'objectclass': 'extensibleObject',
+ 'userpassword': PASSWORD})
+ user.create(properties=user_props, basedn=SUFFIX)
+
+ topo.standalone.log.info("Add {}".format(BIND_DN2))
+ user2 = UserAccount(topo.standalone, BIND_DN2)
+ user_props = TEST_USER_PROPERTIES.copy()
+ user_props.update({'sn': BIND_RDN2,
+ 'cn': BIND_RDN2,
+ 'uid': BIND_RDN2,
+ 'userpassword': PASSWORD})
+ user2.create(properties=user_props, basedn=SUFFIX)
+
+
+def test_multi_deny_aci(topo, aci_setup):
+ """Test that mutliple deny rules work, and that they the cache properly
+ stores the result
+
+ :id: 294c366d-850e-459e-b5a0-3cc828ec3aca
+ :setup: Standalone Instance
+ :steps:
+ 1. Add aci_list_A aci's and verify two searches on the same connection
+ behave the same
+ 2. Add aci_list_B aci's and verify search fails as expected
+ :expectedresults:
+ 1. Both searches do not return any entries
+ 2. Seaches do not return any entries
+ """
+
+ if DEBUGGING:
+ # Maybe add aci logging?
+ pass
+
+ suffix = Domain(topo.standalone, DEFAULT_SUFFIX)
+
+ for run in range(2):
+ topo.standalone.log.info("Pass " + str(run + 1))
+
+ # Test ACI List A
+ topo.standalone.log.info("Testing two searches behave the same...")
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+ suffix.set('aci', aci_list_A, ldap.MOD_REPLACE)
+ time.sleep(1)
+
+ topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user")
+ assert False
+
+ # Bind a different user who has rights
+ topo.standalone.simple_bind_s(BIND_DN2, PASSWORD)
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user (2)")
+ assert False
+
+ if run > 0:
+ # Second pass
+ topo.standalone.restart()
+
+ # Reset ACI's and do the second test
+ topo.standalone.log.info("Testing search does not return any entries...")
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+ suffix.set('aci', aci_list_B, ldap.MOD_REPLACE)
+ time.sleep(1)
+
+ topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+ assert False
+
+ if run > 0:
+ # Second pass
+ topo.standalone.restart()
+
+ # Bind as different user who has rights
+ topo.standalone.simple_bind_s(BIND_DN2, PASSWORD)
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as good user (2)")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+ assert False
+
+ # back to user 1
+ topo.standalone.simple_bind_s(BIND_DN, PASSWORD)
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as user1")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER2)
+ if entries is None or len(entries) == 0:
+ topo.standalone.log.fatal("Failed to get entry as user1 (2)")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 1")
+ assert False
+
+ entries = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, SRCH_FILTER)
+ if entries and entries[0]:
+ topo.standalone.log.fatal("Incorrectly got an entry returned from search 2")
+ assert False
+
+ topo.standalone.log.info("Test PASSED")
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main(["-s", CURRENT_FILE])
+
=====================================
dirsrvtests/tests/suites/replication/cascading_test.py
=====================================
--- /dev/null
+++ b/dirsrvtests/tests/suites/replication/cascading_test.py
@@ -0,0 +1,150 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2018 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+import pytest
+import os
+import ldap
+from lib389._constants import *
+from lib389.replica import ReplicationManager
+from lib389.plugins import MemberOfPlugin
+from lib389.agreement import Agreements
+from lib389.idm.user import UserAccount, TEST_USER_PROPERTIES
+from lib389.idm.group import Groups
+from lib389.topologies import topology_m1h1c1 as topo
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+ logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+BIND_DN = 'uid=tuser1,ou=People,dc=example,dc=com'
+BIND_RDN = 'tuser1'
+
+
+def config_memberof(server):
+ """Configure memberOf plugin and configure fractional
+ to prevent total init to send memberof
+ """
+
+ memberof = MemberOfPlugin(server)
+ memberof.enable()
+ memberof.set_autoaddoc('nsMemberOf')
+ server.restart()
+ agmts = Agreements(server)
+ for agmt in agmts.list():
+ log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % agmt.dn)
+ agmt.replace_many(('nsDS5ReplicatedAttributeListTotal', '(objectclass=*) $ EXCLUDE '),
+ ('nsDS5ReplicatedAttributeList', '(objectclass=*) $ EXCLUDE memberOf'))
+
+
+def test_basic_with_hub(topo):
+ """Check that basic operations work in cascading replication, this includes
+ testing plugins that perform internal operatons, and replicated password
+ policy state attributes.
+
+ :id: 4ac85552-45bc-477b-89a4-226dfff8c6cc
+ :setup: 1 master, 1 hub, 1 consumer
+ :steps:
+ 1. Enable memberOf plugin and set password account lockout settings
+ 2. Restart the instance
+ 3. Add a user
+ 4. Add a group
+ 5. Test that the replication works
+ 6. Add the user as a member to the group
+ 7. Test that the replication works
+ 8. Issue bad binds to update passwordRetryCount
+ 9. Test that replicaton works
+ 10. Check that passwordRetyCount was replicated
+ :expectedresults:
+ 1. Should be a success
+ 2. Should be a success
+ 3. Should be a success
+ 4. Should be a success
+ 5. Should be a success
+ 6. Should be a success
+ 7. Should be a success
+ 8. Should be a success
+ 9. Should be a success
+ 10. Should be a success
+ """
+
+ repl_manager = ReplicationManager(DEFAULT_SUFFIX)
+ master = topo.ms["master1"]
+ consumer = topo.cs["consumer1"]
+ hub = topo.hs["hub1"]
+
+ for inst in topo:
+ config_memberof(inst)
+ inst.config.set('passwordlockout', 'on')
+ inst.config.set('passwordlockoutduration', '60')
+ inst.config.set('passwordmaxfailure', '3')
+ inst.config.set('passwordIsGlobalPolicy', 'on')
+
+ # Create user
+ user1 = UserAccount(master, BIND_DN)
+ user_props = TEST_USER_PROPERTIES.copy()
+ user_props.update({'sn': BIND_RDN,
+ 'cn': BIND_RDN,
+ 'uid': BIND_RDN,
+ 'inetUserStatus': '1',
+ 'objectclass': 'extensibleObject',
+ 'userpassword': PASSWORD})
+ user1.create(properties=user_props, basedn=SUFFIX)
+
+ # Create group
+ groups = Groups(master, DEFAULT_SUFFIX)
+ group = groups.create(properties={'cn': 'group'})
+
+ # Test replication
+ repl_manager.test_replication(master, consumer)
+
+ # Trigger memberOf plugin by adding user to group
+ group.replace('member', user1.dn)
+
+ # Test replication once more
+ repl_manager.test_replication(master, consumer)
+
+ # Issue bad password to update passwordRetryCount
+ try:
+ master.simple_bind_s(user1.dn, "badpassword")
+ except:
+ pass
+
+ # Test replication one last time
+ master.simple_bind_s(DN_DM, PASSWORD)
+ repl_manager.test_replication(master, consumer)
+
+ # Finally check if passwordRetyCount was replicated to the hub and consumer
+ user1 = UserAccount(hub, BIND_DN)
+ count = user1.get_attr_val_int('passwordRetryCount')
+ if count is None:
+ log.fatal('PasswordRetyCount was not replicated to hub')
+ assert False
+ if int(count) != 1:
+ log.fatal('PasswordRetyCount has unexpected value: {}'.format(count))
+ assert False
+
+ user1 = UserAccount(consumer, BIND_DN)
+ count = user1.get_attr_val_int('passwordRetryCount')
+ if count is None:
+ log.fatal('PasswordRetyCount was not replicated to consumer')
+ assert False
+ if int(count) != 1:
+ log.fatal('PasswordRetyCount has unexpected value: {}'.format(count))
+ assert False
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main(["-s", CURRENT_FILE])
+
=====================================
ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
=====================================
--- /dev/null
+++ b/ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
@@ -0,0 +1,38 @@
+dn: cn=CRYPT-MD5,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-MD5
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_md5_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
+
+dn: cn=CRYPT-SHA256,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-SHA256
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_sha256_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
+
+dn: cn=CRYPT-SHA512,cn=Password Storage Schemes,cn=plugins,cn=config
+objectClass: top
+objectClass: nsSlapdPlugin
+cn: CRYPT-SHA512
+nsslapd-pluginPath: libpwdstorage-plugin
+nsslapd-pluginInitfunc: crypt_sha512_pwd_storage_scheme_init
+nsslapd-pluginType: pwdstoragescheme
+nsslapd-pluginEnabled: on
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
=====================================
ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
=====================================
--- /dev/null
+++ b/ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
@@ -0,0 +1,12 @@
+dn: cn=PBKDF2_SHA256,cn=Password Storage Schemes,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+cn: PBKDF2_SHA256
+nsslapd-pluginpath: libpwdstorage-plugin
+nsslapd-plugininitfunc: pbkdf2_sha256_pwd_storage_scheme_init
+nsslapd-plugintype: pwdstoragescheme
+nsslapd-pluginenabled: on
+nsslapd-pluginDescription: DESC
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginid: ID
=====================================
ldap/servers/plugins/acl/acl.c
=====================================
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -1088,9 +1088,23 @@ acl_read_access_allowed_on_entry(
** a DENY rule, then we don't have access to
** the entry ( nice trick to get in )
*/
- if (aclpb->aclpb_state &
- ACLPB_EXECUTING_DENY_HANDLES)
+ if (aclpb->aclpb_state & ACLPB_EXECUTING_DENY_HANDLES) {
+ aclEvalContext *c_ContextEval = &aclpb->aclpb_curr_entryEval_context;
+ AclAttrEval *c_attrEval = NULL;
+ /*
+ * The entire entry is blocked, but previously evaluated allow aci's might
+ * show some of the attributes as readable in the acl cache, so reset all
+ * the cached attributes' status to FAIL.
+ */
+ for (size_t j = 0; j < c_ContextEval->acle_numof_attrs; j++) {
+ c_attrEval = &c_ContextEval->acle_attrEval[j];
+ c_attrEval->attrEval_r_status &= ~ACL_ATTREVAL_SUCCESS;
+ c_attrEval->attrEval_r_status |= ACL_ATTREVAL_FAIL;
+ c_attrEval->attrEval_s_status &= ~ACL_ATTREVAL_SUCCESS;
+ c_attrEval->attrEval_s_status |= ACL_ATTREVAL_FAIL;
+ }
return LDAP_INSUFFICIENT_ACCESS;
+ }
/* The other case is I don't have an
** explicit allow rule -- which is fine.
@@ -2908,6 +2922,12 @@ acl__TestRights(Acl_PBlock *aclpb, int access, const char **right, const char **
result_reason->deciding_aci = NULL;
result_reason->reason = ACL_REASON_NO_MATCHED_RESOURCE_ALLOWS;
+ /* If we have deny handles we should process them */
+ if (aclpb->aclpb_num_deny_handles > 0) {
+ aclpb->aclpb_state &= ~ACLPB_EXECUTING_ALLOW_HANDLES;
+ aclpb->aclpb_state |= ACLPB_EXECUTING_DENY_HANDLES;
+ }
+
TNF_PROBE_1_DEBUG(acl__TestRights_end, "ACL", "",
tnf_string, no_allows, "");
=====================================
ldap/servers/plugins/pwdstorage/crypt_pwd.c
=====================================
--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
@@ -20,19 +20,9 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
-#if defined(hpux) || defined(LINUX) || defined(__FreeBSD__)
-#ifndef __USE_XOPEN
-#define __USE_XOPEN /* linux */
-#endif /* __USE_XOPEN */
-#include <unistd.h>
-#else /* hpux */
-#include <crypt.h>
-#endif /* hpux */
-
+#include <crypt.h> /* for crypt_r */
#include "pwdstorage.h"
-static PRLock *cryptlock = NULL; /* Some implementations of crypt are not thread safe. ie. ours & Irix */
-
/* characters used in crypt encoding */
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -44,38 +34,20 @@ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
int
-crypt_start(Slapi_PBlock *pb __attribute__((unused)))
-{
- if (!cryptlock) {
- cryptlock = PR_NewLock();
- }
- return 0;
-}
-
-int
-crypt_close(Slapi_PBlock *pb __attribute__((unused)))
-{
- if (cryptlock) {
- PR_DestroyLock(cryptlock);
- cryptlock = NULL;
- }
- return 0;
-}
-
-int
crypt_pw_cmp(const char *userpwd, const char *dbpwd)
{
int rc;
char *cp;
- PR_Lock(cryptlock);
- /* we use salt (first 2 chars) of encoded password in call to crypt() */
- cp = crypt(userpwd, dbpwd);
+ struct crypt_data data;
+ data.initialized = 0;
+
+ /* we use salt (first 2 chars) of encoded password in call to crypt_r() */
+ cp = crypt_r(userpwd, dbpwd, &data);
if (cp) {
rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd));
} else {
rc = -1;
}
- PR_Unlock(cryptlock);
return rc;
}
@@ -88,6 +60,8 @@ crypt_pw_enc_by_hash(const char *pwd, int hash_algo)
char *enc = NULL;
long v;
static unsigned int seed = 0;
+ struct crypt_data data;
+ data.initialized = 0;
if (seed == 0) {
seed = (unsigned int)slapi_rand();
@@ -113,12 +87,10 @@ crypt_pw_enc_by_hash(const char *pwd, int hash_algo)
algo_salt = strdup(salt);
}
- PR_Lock(cryptlock);
- cry = crypt(pwd, algo_salt);
+ cry = crypt_r(pwd, algo_salt, &data);
if (cry != NULL) {
enc = slapi_ch_smprintf("%c%s%c%s", PWD_HASH_PREFIX_START, CRYPT_SCHEME_NAME, PWD_HASH_PREFIX_END, cry);
}
- PR_Unlock(cryptlock);
slapi_ch_free_string(&algo_salt);
return (enc);
=====================================
ldap/servers/plugins/pwdstorage/pwd_init.c
=====================================
--- a/ldap/servers/plugins/pwdstorage/pwd_init.c
+++ b/ldap/servers/plugins/pwdstorage/pwd_init.c
@@ -245,8 +245,6 @@ crypt_pwd_storage_scheme_init(Slapi_PBlock *pb)
(void *)SLAPI_PLUGIN_VERSION_01);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&crypt_pdesc);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
(void *)crypt_pw_enc);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -269,8 +267,6 @@ crypt_md5_pwd_storage_scheme_init(Slapi_PBlock *pb)
(void *)SLAPI_PLUGIN_VERSION_01);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&crypt_md5_pdesc);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
(void *)crypt_pw_md5_enc);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -293,8 +289,6 @@ crypt_sha256_pwd_storage_scheme_init(Slapi_PBlock *pb)
(void *)SLAPI_PLUGIN_VERSION_01);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&crypt_sha256_pdesc);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
(void *)crypt_pw_sha256_enc);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
@@ -317,8 +311,6 @@ crypt_sha512_pwd_storage_scheme_init(Slapi_PBlock *pb)
(void *)SLAPI_PLUGIN_VERSION_01);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&crypt_sha512_pdesc);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)&crypt_start);
- rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)&crypt_close);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
(void *)crypt_pw_sha512_enc);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
=====================================
ldap/servers/plugins/pwdstorage/pwdstorage.h
=====================================
--- a/ldap/servers/plugins/pwdstorage/pwdstorage.h
+++ b/ldap/servers/plugins/pwdstorage/pwdstorage.h
@@ -74,8 +74,6 @@ char *sha512_pw_enc(const char *pwd);
char *salted_sha512_pw_enc(const char *pwd);
int clear_pw_cmp(const char *userpwd, const char *dbpwd);
char *clear_pw_enc(const char *pwd);
-int crypt_start(Slapi_PBlock *pb);
-int crypt_close(Slapi_PBlock *pb);
int crypt_pw_cmp(const char *userpwd, const char *dbpwd);
char *crypt_pw_enc(const char *pwd);
char *crypt_pw_md5_enc(const char *pwd);
=====================================
ldap/servers/plugins/replication/repl5_agmt.c
=====================================
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2523,7 +2523,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
replmsg = NULL;
}
}
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s%s%s",
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s%sLDAP error: %s%s%s%s%s",
ldaprc, message ? message : "", message ? "" : " - ",
slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "",
connrc ? " - " : "", connrc ? connmsg : "");
@@ -2531,7 +2531,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
/* ldaprc == LDAP_SUCCESS */
else if (replrc != 0) {
if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) {
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s",
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s",
ldaprc, "Replication session successful");
} else if (replrc == NSDS50_REPL_DISABLED) {
if (agmt_is_enabled(ra)) {
@@ -2539,7 +2539,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
"Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n"
"You must enable it then restart the server for replication to take place).\n",
ra->long_name ? ra->long_name : "a replica");
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d Total update aborted: "
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: "
"Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n"
"You must enable it then restart the server for replication to take place).",
replrc, ra->long_name ? ra->long_name : "a replica");
@@ -2548,29 +2548,29 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: "
"Replication agreement for \"%s\" can not be updated while the agreement is disabled\n",
ra->long_name ? ra->long_name : "a replica");
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d Total update aborted: "
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: "
"Replication agreement for \"%s\" can not be updated while the agreement is disabled.",
replrc, ra->long_name ? ra->long_name : "a replica");
}
} else {
PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d Replication error acquiring replica: %s%s%s%s%s",
+ "Error (%d) Replication error acquiring replica: %s%s%s%s%s",
replrc, protocol_response2string(replrc),
message ? " - " : "", message ? message : "",
connrc ? " - " : "", connrc ? connmsg : "");
}
} else if (connrc != CONN_OPERATION_SUCCESS) {
PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d connection error: %s%s%s",
+ "Error (%d) connection error: %s%s%s",
connrc, connmsg,
message ? " - " : "", message ? message : "");
} else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
{
PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d %s",
+ "Error (%d) %s",
ldaprc, message);
} else { /* agmt_set_last_init_status(0,0,NULL) to reset agmt */
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d", ldaprc);
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)", ldaprc);
}
}
}
=====================================
ldap/servers/plugins/replication/repl5_plugins.c
=====================================
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1059,6 +1059,16 @@ write_changelog_and_ruv(Slapi_PBlock *pb)
goto common_return;
}
+ /* Skip internal operations with no op csn if this is a read-only replica */
+ if (op_params->csn == NULL &&
+ operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
+ replica_get_type(r) == REPLICA_TYPE_READONLY)
+ {
+ slapi_log_err(SLAPI_LOG_REPL, "write_changelog_and_ruv",
+ "Skipping internal operation on read-only replica\n");
+ goto common_return;
+ }
+
/* we might have stripped all the mods - in that case we do not
log the operation */
if (op_params->operation_type != SLAPI_OPERATION_MODIFY ||
=====================================
ldap/servers/plugins/replication/urp_tombstone.c
=====================================
--- a/ldap/servers/plugins/replication/urp_tombstone.c
+++ b/ldap/servers/plugins/replication/urp_tombstone.c
@@ -51,97 +51,94 @@ get_tombstone_csn(const Slapi_Entry *entry, const CSN **delcsn)
return ists;
}
-static Slapi_DN*
+static Slapi_DN *
get_valid_parent_for_conflict(Slapi_Entry *entry)
{
- char *replconflict = slapi_entry_attr_get_charptr(entry,ATTR_NSDS5_REPLCONFLICT );
- char *validdn = NULL;
- Slapi_DN *valid_DN = NULL;
-
- if (replconflict) {
- validdn = strstr(replconflict, " (ADD) ");
- if (validdn) {
- validdn += 7;
- valid_DN = slapi_sdn_new_dn_byval(validdn);
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "get_valid_parent_for_conflict - valid entry dn: %s\n",
- validdn);
- }
- slapi_ch_free_string(&replconflict);
- }
- return valid_DN;
+ char *replconflict = slapi_entry_attr_get_charptr(entry, ATTR_NSDS5_REPLCONFLICT);
+ char *validdn = NULL;
+ Slapi_DN *valid_DN = NULL;
+
+ if (replconflict) {
+ validdn = strstr(replconflict, " (ADD) ");
+ if (validdn) {
+ validdn += 7;
+ valid_DN = slapi_sdn_new_dn_byval(validdn);
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "get_valid_parent_for_conflict - valid entry dn: %s\n",
+ validdn);
+ }
+ slapi_ch_free_string(&replconflict);
+ }
+ return valid_DN;
}
int
-tombstone_to_conflict_check_parent (
- char *sessionid,
- char *parentdn,
- const char *uniqueid,
- const char *parentuniqueid,
- CSN *opcsn,
- Slapi_DN *conflictdn)
+tombstone_to_conflict_check_parent(
+ char *sessionid,
+ char *parentdn,
+ const char *uniqueid,
+ const char *parentuniqueid,
+ CSN *opcsn,
+ Slapi_DN *conflictdn)
{
- int rc = 0;
- int op_result;
- Slapi_PBlock *newpb;
-
- if (parentdn == 0) {
- slapi_log_err(SLAPI_LOG_REPL, sessionid,
- "tombstone_to_conflict_check_parent - no parent entry for: %s\n",
- slapi_sdn_get_ndn(conflictdn));
- return rc;
- } else {
- slapi_log_err(SLAPI_LOG_REPL, sessionid,
- "tombstone_to_conflict_check_parent - checking parent entry: %s\n",
- parentdn);
- }
- newpb = slapi_pblock_new();
- slapi_search_internal_set_pb(
- newpb,
- parentdn,
- LDAP_SCOPE_BASE,
- "objectclass=*",
- NULL, /*attrs*/
- 0, /*attrsonly*/
- NULL, /*Controls*/
- parentuniqueid, /*uniqueid*/
- repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
- 0);
- slapi_search_internal_pb(newpb);
- slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &op_result);
- switch(op_result)
- {
- case LDAP_SUCCESS:
- {
- Slapi_Entry **entries= NULL;
- slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
- if(entries!=NULL && entries[0]!=NULL) {
- if(is_conflict_entry(entries[0])) {
- Slapi_DN *newsuperior = get_valid_parent_for_conflict(entries[0]);
- Slapi_RDN *rdn = slapi_rdn_new();
- slapi_sdn_get_rdn(conflictdn, rdn);
- const char *newrdn = slapi_rdn_get_rdn(rdn);
- op_result= urp_fixup_modrdn_entry(
- conflictdn,
- newrdn,
- newsuperior,
- uniqueid,
- NULL,
- NULL,
- OP_FLAG_NOOP);
- slapi_rdn_free(&rdn);
- slapi_sdn_free(&newsuperior);
- }
- }
- }
- break;
- default:
- break;
- }
+ int rc = 0;
+ int op_result;
+ Slapi_PBlock *newpb;
- slapi_free_search_results_internal (newpb);
- slapi_pblock_destroy(newpb);
- return rc;
+ if (parentdn == 0) {
+ slapi_log_err(SLAPI_LOG_REPL, sessionid,
+ "tombstone_to_conflict_check_parent - no parent entry for: %s\n",
+ slapi_sdn_get_ndn(conflictdn));
+ return rc;
+ } else {
+ slapi_log_err(SLAPI_LOG_REPL, sessionid,
+ "tombstone_to_conflict_check_parent - checking parent entry: %s\n",
+ parentdn);
+ }
+ newpb = slapi_pblock_new();
+ slapi_search_internal_set_pb(
+ newpb,
+ parentdn,
+ LDAP_SCOPE_BASE,
+ "objectclass=*",
+ NULL, /*attrs*/
+ 0, /*attrsonly*/
+ NULL, /*Controls*/
+ parentuniqueid, /*uniqueid*/
+ repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+ 0);
+ slapi_search_internal_pb(newpb);
+ slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &op_result);
+ switch (op_result) {
+ case LDAP_SUCCESS: {
+ Slapi_Entry **entries = NULL;
+ slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ if (entries != NULL && entries[0] != NULL) {
+ if (is_conflict_entry(entries[0])) {
+ Slapi_DN *newsuperior = get_valid_parent_for_conflict(entries[0]);
+ Slapi_RDN *rdn = slapi_rdn_new();
+ slapi_sdn_get_rdn(conflictdn, rdn);
+ const char *newrdn = slapi_rdn_get_rdn(rdn);
+ op_result = urp_fixup_modrdn_entry(
+ conflictdn,
+ newrdn,
+ newsuperior,
+ uniqueid,
+ NULL,
+ NULL,
+ OP_FLAG_NOOP);
+ slapi_rdn_free(&rdn);
+ slapi_sdn_free(&newsuperior);
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ slapi_free_search_results_internal(newpb);
+ slapi_pblock_destroy(newpb);
+ return rc;
}
static int
@@ -205,106 +202,108 @@ tombstone_to_glue_resolve_parent(
int
conflict_to_tombstone(char *sessionid, Slapi_Entry *entry, CSN *opcsn)
{
- int op_result = 0;
- Slapi_RDN *srdn = slapi_rdn_new();
- const char *uniqueid = slapi_entry_get_uniqueid ( entry );
- const char *newrdn = NULL;
- char *conflictdn = NULL;
- char *replconflict = slapi_entry_attr_get_charptr(entry,ATTR_NSDS5_REPLCONFLICT );
-
- if (replconflict) {
- conflictdn = strstr(replconflict, " (ADD) ");
- if (conflictdn == NULL) {
- /* error, wrong type of conflict */
- op_result = 1;
- } else {
- conflictdn += 7;
- slapi_rdn_init_all_dn(srdn, conflictdn);
- newrdn = slapi_rdn_get_nrdn(srdn);
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "conflict_to_tombstone - %s - valid entry dn: %s newrdn: %s\n",
- sessionid, conflictdn, newrdn);
- }
- }
+ int op_result = 0;
+ Slapi_RDN *srdn = slapi_rdn_new();
+ const char *uniqueid = slapi_entry_get_uniqueid(entry);
+ const char *newrdn = NULL;
+ char *conflictdn = NULL;
+ char *replconflict = slapi_entry_attr_get_charptr(entry, ATTR_NSDS5_REPLCONFLICT);
+
+ if (replconflict) {
+ conflictdn = strstr(replconflict, " (ADD) ");
+ if (conflictdn == NULL) {
+ /* error, wrong type of conflict */
+ op_result = 1;
+ } else {
+ conflictdn += 7;
+ slapi_rdn_init_all_dn(srdn, conflictdn);
+ newrdn = slapi_rdn_get_nrdn(srdn);
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "conflict_to_tombstone - %s - valid entry dn: %s newrdn: %s\n",
+ sessionid, conflictdn, newrdn);
+ }
+ }
- if (op_result) goto done;
+ if (op_result)
+ goto done;
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "conflict_to_tombstone - %s - Renaming entry %s to %s\n",
- sessionid, slapi_entry_get_dn_const (entry), newrdn);
- op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP);
- if (op_result) goto done;
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "conflict_to_tombstone - %s - Renaming entry %s to %s\n",
+ sessionid, slapi_entry_get_dn_const(entry), newrdn);
+ op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP);
+ if (op_result)
+ goto done;
- op_result = urp_fixup_delete_entry (uniqueid, slapi_entry_get_dn_const (entry), opcsn, 0);
+ op_result = urp_fixup_delete_entry(uniqueid, slapi_entry_get_dn_const(entry), opcsn, 0);
-done:
- slapi_ch_free_string(&replconflict);
- slapi_rdn_free(&srdn);
- return op_result;
+done:
+ slapi_ch_free_string(&replconflict);
+ slapi_rdn_free(&srdn);
+ return op_result;
}
/*
* Convert a tombstone into a conflict entry.
*/
int
-tombstone_to_conflict (
- char *sessionid,
- Slapi_Entry *tombstoneentry,
- const Slapi_DN *conflictdn,
- const char *reason,
- CSN *opcsn,
- Slapi_DN **newparentdn)
+tombstone_to_conflict(
+ char *sessionid,
+ Slapi_Entry *tombstoneentry,
+ const Slapi_DN *conflictdn,
+ const char *reason,
+ CSN *opcsn,
+ Slapi_DN **newparentdn)
{
- int op_result = 0;
- Slapi_Mods smods;
- char csnstr[CSN_STRSIZE+1];
- char buf[BUFSIZ];
- char *uniqueid = slapi_entry_attr_get_charptr(tombstoneentry, "nsuiqueid");
- char *entrydn = slapi_entry_attr_get_charptr(tombstoneentry, "nscpentrydn");
- char *parentuniqueid = slapi_entry_attr_get_charptr (tombstoneentry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID); /* Allocated */
- char *parentdn = slapi_dn_parent(slapi_sdn_get_ndn(conflictdn));
- const CSN *dncsn = entry_get_dncsn(tombstoneentry);
- csn_as_string(dncsn, PR_FALSE, csnstr);
-
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "tombstone_to_conflict - %s - trying to resurrect tombstone as '%s'.\n",
- sessionid, slapi_sdn_get_ndn(conflictdn));
- slapi_sdn_set_normdn_byval(slapi_entry_get_sdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
- /* not just e_sdn, e_rsdn needs to be updated. */
- slapi_rdn_set_all_dn(slapi_entry_get_srdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
- op_result = urp_fixup_add_entry (tombstoneentry, NULL, NULL, opcsn, OP_FLAG_RESURECT_ENTRY|OP_FLAG_NOOP);
-
- if (op_result) {
- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
- "tombstone_to_conflict - %s - Can't resurrect tombstone, error=%d\n",
- sessionid, op_result);
- goto done;
- }
+ int op_result = 0;
+ Slapi_Mods smods;
+ char csnstr[CSN_STRSIZE + 1];
+ char buf[BUFSIZ];
+ char *uniqueid = slapi_entry_attr_get_charptr(tombstoneentry, "nsuiqueid");
+ char *entrydn = slapi_entry_attr_get_charptr(tombstoneentry, "nscpentrydn");
+ char *parentuniqueid = slapi_entry_attr_get_charptr(tombstoneentry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID); /* Allocated */
+ char *parentdn = slapi_dn_parent(slapi_sdn_get_ndn(conflictdn));
+ const CSN *dncsn = entry_get_dncsn(tombstoneentry);
+ csn_as_string(dncsn, PR_FALSE, csnstr);
+
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "tombstone_to_conflict - %s - trying to resurrect tombstone as '%s'.\n",
+ sessionid, slapi_sdn_get_ndn(conflictdn));
+ slapi_sdn_set_normdn_byval(slapi_entry_get_sdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
+ /* not just e_sdn, e_rsdn needs to be updated. */
+ slapi_rdn_set_all_dn(slapi_entry_get_srdn(tombstoneentry), slapi_sdn_get_ndn(conflictdn));
+ op_result = urp_fixup_add_entry(tombstoneentry, NULL, NULL, opcsn, OP_FLAG_RESURECT_ENTRY | OP_FLAG_NOOP);
- slapi_mods_init (&smods, 5);
- slapi_mods_add (&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry");
- slapi_mods_add (&smods, LDAP_MOD_DELETE, "objectclass", strlen("glue"),"glue");
- slapi_mods_add (&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr), csnstr);
- PR_snprintf (buf, sizeof(buf), "%s (%s) %s",
- REASON_ANNOTATE_DN, "ADD", entrydn);
- slapi_mods_add (&smods, LDAP_MOD_ADD, ATTR_NSDS5_REPLCONFLICT, strlen(buf), buf);
- op_result = urp_fixup_modify_entry (uniqueid, conflictdn, opcsn, &smods, 0);
- slapi_mods_done (&smods);
- if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
- /* the objectclass was already present */
- op_result = LDAP_SUCCESS;
- }
- /* this will go to postop
+ if (op_result) {
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
+ "tombstone_to_conflict - %s - Can't resurrect tombstone, error=%d\n",
+ sessionid, op_result);
+ goto done;
+ }
+
+ slapi_mods_init(&smods, 5);
+ slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"), "ldapsubentry");
+ slapi_mods_add(&smods, LDAP_MOD_DELETE, "objectclass", strlen("glue"), "glue");
+ slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr), csnstr);
+ PR_snprintf(buf, sizeof(buf), "%s (%s) %s",
+ REASON_ANNOTATE_DN, "ADD", entrydn);
+ slapi_mods_add(&smods, LDAP_MOD_ADD, ATTR_NSDS5_REPLCONFLICT, strlen(buf), buf);
+ op_result = urp_fixup_modify_entry(uniqueid, conflictdn, opcsn, &smods, 0);
+ slapi_mods_done(&smods);
+ if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
+ /* the objectclass was already present */
+ op_result = LDAP_SUCCESS;
+ }
+/* this will go to postop
if (op_result == LDAP_SUCCESS) {
op_result = tombstone_to_conflict_check_parent(sessionid, parentdn, uniqueid, parentuniqueid, opcsn, conflictdn);
}
*/
done:
- slapi_ch_free_string(&uniqueid);
- slapi_ch_free_string(&parentuniqueid);
- slapi_ch_free_string(&parentdn);
- slapi_ch_free_string(&entrydn);
- return op_result;
+ slapi_ch_free_string(&uniqueid);
+ slapi_ch_free_string(&parentuniqueid);
+ slapi_ch_free_string(&parentdn);
+ slapi_ch_free_string(&entrydn);
+ return op_result;
}
/*
=====================================
ldap/servers/slapd/back-ldbm/monitor.c
=====================================
--- a/ldap/servers/slapd/back-ldbm/monitor.c
+++ b/ldap/servers/slapd/back-ldbm/monitor.c
@@ -157,7 +157,7 @@ ldbm_back_monitor_instance_search(Slapi_PBlock *pb __attribute__((unused)),
#ifdef DEBUG
{
/* debugging for hash statistics */
- char *x;
+ char *x = NULL;
cache_debug_hash(&(inst->inst_cache), &x);
val.bv_val = x;
val.bv_len = strlen(x);
=====================================
ldap/servers/slapd/connection.c
=====================================
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -1716,7 +1716,9 @@ connection_threadmain()
if ((tag != LDAP_REQ_UNBIND) && !thread_turbo_flag && !replication_connection) {
if (!more_data) {
conn->c_flags &= ~CONN_FLAG_MAX_THREADS;
+ PR_EnterMonitor(conn->c_mutex);
connection_make_readable_nolock(conn);
+ PR_ExitMonitor(conn->c_mutex);
/* once the connection is readable, another thread may access conn,
* so need locking from here on */
signal_listner();
@@ -1822,9 +1824,17 @@ connection_threadmain()
/* If we're in turbo mode, we keep our reference to the connection alive */
/* can't use the more_data var because connection could have changed in another thread */
- more_data = conn_buffered_data_avail_nolock(conn, &conn_closed) ? 1 : 0;
- slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", "conn %" PRIu64 " check more_data %d thread_turbo_flag %d\n",
- conn->c_connid, more_data, thread_turbo_flag);
+ slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", "conn %" PRIu64 " check more_data %d thread_turbo_flag %d"
+ "repl_conn_bef %d, repl_conn_now %d\n",
+ conn->c_connid, more_data, thread_turbo_flag,
+ replication_connection, conn->c_isreplication_session);
+ if (!replication_connection && conn->c_isreplication_session) {
+ /* it a connection that was just flagged as replication connection */
+ more_data = 0;
+ } else {
+ /* normal connection or already established replication connection */
+ more_data = conn_buffered_data_avail_nolock(conn, &conn_closed) ? 1 : 0;
+ }
if (!more_data) {
if (!thread_turbo_flag) {
/*
=====================================
ldap/servers/slapd/csngen.c
=====================================
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -331,14 +331,18 @@ csngen_adjust_time(CSNGen *gen, const CSN *csn)
/* let's revisit the seq num - if the new time is > the old
tiem, we should reset the seq number to remote + 1 if
this won't cause a wrap around */
- if (new_time > cur_time) {
+ if (new_time >= cur_time) {
/* just set seq_num regardless of whether the current one
is < or > than the remote one - the goal of this function
is to make sure we generate CSNs > the remote CSN - if
we have increased the time, we can decrease the seqnum
and still guarantee that any new CSNs generated will be
> any current CSNs we have generated */
- gen->state.seq_num = remote_seqnum + 1;
+ if (remote_seqnum < gen->state.seq_num) {
+ gen->state.seq_num ++;
+ } else {
+ gen->state.seq_num = remote_seqnum + 1;
+ }
}
if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
slapi_log_err(SLAPI_LOG_REPL, "csngen_adjust_time",
=====================================
ldap/servers/slapd/daemon.c
=====================================
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -1087,12 +1087,18 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
/* we have exited from ns_thrpool_wait. This means we are shutting down! */
/* Please see https://firstyear.fedorapeople.org/nunc-stans/md_docs_job-safety.html */
/* tldr is shutdown needs to run first to allow job_done on an ARMED job */
- for (size_t i = 0; i < listeners; i++) {
- PRStatus shutdown_status = ns_job_done(listener_idxs[i].ns_job);
- if (shutdown_status != PR_SUCCESS) {
- slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed to shutdown listener idx %" PRIu64 " !\n", i);
+ for (uint64_t i = 0; i < listeners; i++) {
+ PRStatus shutdown_status;
+
+ if (listener_idxs[i].ns_job) {
+ shutdown_status = ns_job_done(listener_idxs[i].ns_job);
+ if (shutdown_status != PR_SUCCESS) {
+ slapi_log_err(SLAPI_LOG_CRIT, "ns_set_shutdown", "Failed to shutdown listener idx %" PRIu64 " !\n", i);
+ }
+ PR_ASSERT(shutdown_status == PR_SUCCESS);
+ } else {
+ slapi_log_err(SLAPI_LOG_CRIT, "slapd_daemon", "Listeners uninitialized. Possibly the server was shutdown while starting\n");
}
- PR_ASSERT(shutdown_status == PR_SUCCESS);
listener_idxs[i].ns_job = NULL;
}
} else {
@@ -1197,8 +1203,10 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
* All the connection close jobs "should" complete before
* shutdown at least.
*/
- ns_thrpool_shutdown(tp);
- ns_thrpool_wait(tp);
+ if (enable_nunc_stans) {
+ ns_thrpool_shutdown(tp);
+ ns_thrpool_wait(tp);
+ }
threads = g_get_active_threadcnt();
if (threads > 0) {
@@ -1676,22 +1684,25 @@ ns_handle_closure(struct ns_job_t *job)
/**
* Schedule more I/O for this connection, or make sure that it
* is closed in the event loop.
+ * caller must hold c_mutex
+ * It returns
+ * 0 on success
+ * 1 on need to retry
*/
-void
-ns_connection_post_io_or_closing(Connection *conn)
+static int
+ns_connection_post_io_or_closing_try(Connection *conn)
{
struct timeval tv;
if (!enable_nunc_stans) {
- return;
+ return 0;
}
/*
* Cancel any existing ns jobs we have registered.
*/
if (conn->c_job != NULL) {
- ns_job_done(conn->c_job);
- conn->c_job = NULL;
+ return 1;
}
if (CONN_NEEDS_CLOSING(conn)) {
@@ -1701,7 +1712,7 @@ ns_connection_post_io_or_closing(Connection *conn)
slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "Already a close "
"job in progress on conn %" PRIu64 " for fd=%d\n",
conn->c_connid, conn->c_sd);
- return;
+ return 0;
} else {
conn->c_ns_close_jobs++; /* now 1 active closure job */
connection_acquire_nolock_ext(conn, 1 /* allow acquire even when closing */); /* event framework now has a reference */
@@ -1745,7 +1756,7 @@ ns_connection_post_io_or_closing(Connection *conn)
* The error occurs when we get a connection in a closing state.
* For now we return, but there is probably a better way to handle the error case.
*/
- return;
+ return 0;
}
#endif
ns_result_t job_result = ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
@@ -1767,6 +1778,28 @@ ns_connection_post_io_or_closing(Connection *conn)
conn->c_connid, conn->c_sd);
}
}
+ return 0;
+}
+void
+ns_connection_post_io_or_closing(Connection *conn)
+{
+ while (ns_connection_post_io_or_closing_try(conn)) {
+ /* we should retry later */
+
+ /* We are not suppose to work immediately on the connection that is taken by
+ * another job
+ * release the lock and give some time
+ */
+
+ if (CONN_NEEDS_CLOSING(conn) && conn->c_ns_close_jobs) {
+ return;
+ } else {
+ PR_ExitMonitor(conn->c_mutex);
+ DS_Sleep(PR_MillisecondsToInterval(100));
+
+ PR_EnterMonitor(conn->c_mutex);
+ }
+ }
}
/* This function must be called without the thread flag, in the
@@ -2467,7 +2500,9 @@ ns_handle_new_connection(struct ns_job_t *job)
* that poll() was avoided, even at the expense of putting this new fd back
* in nunc-stans to poll for read ready.
*/
+ PR_EnterMonitor(c->c_mutex);
ns_connection_post_io_or_closing(c);
+ PR_ExitMonitor(c->c_mutex);
return;
}
=====================================
ldap/servers/slapd/filter.c
=====================================
--- a/ldap/servers/slapd/filter.c
+++ b/ldap/servers/slapd/filter.c
@@ -472,7 +472,7 @@ get_substring_filter(
f->f_sub_initial = val;
eval = (char *)slapi_escape_filter_value(val, -1);
if (eval) {
- if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+ if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
fstr_len += (strlen(eval) + 1) * 2;
*fstr = slapi_ch_realloc(*fstr, fstr_len);
}
@@ -486,7 +486,7 @@ get_substring_filter(
charray_add(&f->f_sub_any, val);
eval = (char *)slapi_escape_filter_value(val, -1);
if (eval) {
- if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+ if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
fstr_len += (strlen(eval) + 1) * 2;
*fstr = slapi_ch_realloc(*fstr, fstr_len);
}
@@ -504,7 +504,7 @@ get_substring_filter(
f->f_sub_final = val;
eval = (char *)slapi_escape_filter_value(val, -1);
if (eval) {
- if (fstr_len < strlen(*fstr) + strlen(eval) + 1) {
+ if (fstr_len <= strlen(*fstr) + strlen(eval) + 1) {
fstr_len += (strlen(eval) + 1) * 2;
*fstr = slapi_ch_realloc(*fstr, fstr_len);
}
@@ -530,7 +530,7 @@ get_substring_filter(
}
filter_compute_hash(f);
- if (fstr_len < strlen(*fstr) + 3) {
+ if (fstr_len <= strlen(*fstr) + 3) {
fstr_len += 3;
*fstr = slapi_ch_realloc(*fstr, fstr_len);
}
=====================================
ldap/servers/slapd/slap.h
=====================================
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1650,7 +1650,7 @@ typedef struct conn
void *c_io_layer_cb_data; /* callback data */
struct connection_table *c_ct; /* connection table that this connection belongs to */
ns_thrpool_t *c_tp; /* thread pool for this connection */
- struct ns_job_t *c_job; /* If it exists, the current ns_job_t */
+ struct ns_job_t *c_job; /* If it exists, the current ns_job_t */
int c_ns_close_jobs; /* number of current close jobs */
char *c_ipaddr; /* ip address str - used by monitor */
} Connection;
=====================================
ldap/servers/slapd/util.c
=====================================
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -161,6 +161,11 @@ do_escape_string(
break;
}
do {
+ if (bufSpace < 4) {
+ memcpy(bufNext, "..", 2);
+ bufNext += 2;
+ goto bail;
+ }
if (esc == UTIL_ESCAPE_BACKSLASH) {
/* *s is '\\' */
/* If *(s+1) and *(s+2) are both hex digits,
@@ -179,11 +184,6 @@ do_escape_string(
*bufNext++ = '\\';
--bufSpace;
}
- if (bufSpace < 3) {
- memcpy(bufNext, "..", 2);
- bufNext += 2;
- goto bail;
- }
PR_snprintf(bufNext, 3, "%02x", *(unsigned char *)s);
bufNext += 2;
bufSpace -= 2;
View it on GitLab: https://salsa.debian.org/freeipa-team/389-ds-base/compare/ce88dd0e9e2dc5eaa397221cf6140af4bd1bd03d...21800c3c1822e44c00304aa04eb4e04eaa55fc48
--
View it on GitLab: https://salsa.debian.org/freeipa-team/389-ds-base/compare/ce88dd0e9e2dc5eaa397221cf6140af4bd1bd03d...21800c3c1822e44c00304aa04eb4e04eaa55fc48
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-freeipa-devel/attachments/20180601/02604eda/attachment-0001.html>
More information about the Pkg-freeipa-devel
mailing list