|
|
b69e47 |
From b0954a5df7841330732a5ab532c528a68cf380cf Mon Sep 17 00:00:00 2001
|
|
|
b69e47 |
From: William Brown <firstyear@redhat.com>
|
|
|
b69e47 |
Date: Fri, 18 Aug 2017 13:00:46 +1000
|
|
|
b69e47 |
Subject: [PATCH] Ticket 49356 - mapping tree crash can occur during tot init
|
|
|
b69e47 |
|
|
|
b69e47 |
Bug Description: Two faults were found in the handling of the mapping
|
|
|
b69e47 |
tree of 389 directory server. The first fault was that the tree-free
|
|
|
b69e47 |
check was not performed atomically and may cause an incorrect operations
|
|
|
b69e47 |
error to be returned. The second was that during a total init the referral
|
|
|
b69e47 |
would not lock the be, but the pw_verify code assumed a be was locked.
|
|
|
b69e47 |
This caused a segfault.
|
|
|
b69e47 |
|
|
|
b69e47 |
Fix Description: Fix the freed check to use atomics. Fix the pw_verify
|
|
|
b69e47 |
to assert be is NULL (which is correct, there is no backend).
|
|
|
b69e47 |
|
|
|
b69e47 |
https://pagure.io/389-ds-base/issue/49356
|
|
|
b69e47 |
|
|
|
b69e47 |
Author: wibrown
|
|
|
b69e47 |
|
|
|
b69e47 |
Review by: mreynolds (THanks!)
|
|
|
b69e47 |
---
|
|
|
b69e47 |
.../mapping_tree/referral_during_tot_init.py | 57 ++++++++
|
|
|
b69e47 |
ldap/servers/slapd/fedse.c | 10 ++
|
|
|
b69e47 |
ldap/servers/slapd/main.c | 10 --
|
|
|
b69e47 |
ldap/servers/slapd/mapping_tree.c | 150 +++++++++++----------
|
|
|
b69e47 |
ldap/servers/slapd/pw_verify.c | 8 +-
|
|
|
b69e47 |
5 files changed, 150 insertions(+), 85 deletions(-)
|
|
|
b69e47 |
create mode 100644 dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
|
|
b69e47 |
|
|
|
b69e47 |
diff --git a/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
|
|
b69e47 |
new file mode 100644
|
|
|
b69e47 |
index 0000000..e5aee7d
|
|
|
b69e47 |
--- /dev/null
|
|
|
b69e47 |
+++ b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
|
|
b69e47 |
@@ -0,0 +1,57 @@
|
|
|
b69e47 |
+# --- BEGIN COPYRIGHT BLOCK ---
|
|
|
b69e47 |
+# Copyright (C) 2017 Red Hat, Inc.
|
|
|
b69e47 |
+# All rights reserved.
|
|
|
b69e47 |
+#
|
|
|
b69e47 |
+# License: GPL (version 3 or any later version).
|
|
|
b69e47 |
+# See LICENSE for details.
|
|
|
b69e47 |
+# --- END COPYRIGHT BLOCK ---
|
|
|
b69e47 |
+#
|
|
|
b69e47 |
+import ldap
|
|
|
b69e47 |
+import pytest
|
|
|
b69e47 |
+from lib389.topologies import topology_m2
|
|
|
b69e47 |
+from lib389._constants import (DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2, TASK_WAIT)
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+from lib389.idm.user import (TEST_USER_PROPERTIES, UserAccounts)
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+def test_referral_during_tot(topology_m2):
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ master1 = topology_m2.ms["master1"]
|
|
|
b69e47 |
+ master2 = topology_m2.ms["master2"]
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ # Create a bunch of entries on master1
|
|
|
b69e47 |
+ ldif_dir = master1.get_ldif_dir()
|
|
|
b69e47 |
+ import_ldif = ldif_dir + '/ref_during_tot_import.ldif'
|
|
|
b69e47 |
+ master1.buildLDIF(10000, import_ldif)
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ master1.stop()
|
|
|
b69e47 |
+ try:
|
|
|
b69e47 |
+ master1.ldif2db(bename=None, excludeSuffixes=None, encrypt=False, suffixes=[DEFAULT_SUFFIX], import_file=import_ldif)
|
|
|
b69e47 |
+ except:
|
|
|
b69e47 |
+ pass
|
|
|
b69e47 |
+ # master1.tasks.importLDIF(suffix=DEFAULT_SUFFIX, input_file=import_ldif, args={TASK_WAIT: True})
|
|
|
b69e47 |
+ master1.start()
|
|
|
b69e47 |
+ users = UserAccounts(master1, DEFAULT_SUFFIX, rdn='ou=Accounting')
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ u = users.create(properties=TEST_USER_PROPERTIES)
|
|
|
b69e47 |
+ u.set('userPassword', 'password')
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ binddn = u.dn
|
|
|
b69e47 |
+ bindpw = 'password'
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ # Now export them to master2
|
|
|
b69e47 |
+ master1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ # While that's happening try to bind as a user to master 2
|
|
|
b69e47 |
+ # This should trigger the referral code.
|
|
|
b69e47 |
+ for i in range(0, 100):
|
|
|
b69e47 |
+ conn = ldap.initialize(master2.toLDAPURL())
|
|
|
b69e47 |
+ conn.set_option(ldap.OPT_REFERRALS, False)
|
|
|
b69e47 |
+ try:
|
|
|
b69e47 |
+ conn.simple_bind_s(binddn, bindpw)
|
|
|
b69e47 |
+ conn.unbind_s()
|
|
|
b69e47 |
+ except ldap.REFERRAL:
|
|
|
b69e47 |
+ pass
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ # Done.
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
|
|
|
b69e47 |
index 13a3c74..c2a862b 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/fedse.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/fedse.c
|
|
|
b69e47 |
@@ -1853,6 +1853,16 @@ setup_internal_backends(char *configdir)
|
|
|
b69e47 |
be_addsuffix(be,&monitor);
|
|
|
b69e47 |
be_addsuffix(be,&config);
|
|
|
b69e47 |
|
|
|
b69e47 |
+ /*
|
|
|
b69e47 |
+ * Now that the be's are in place, we can
|
|
|
b69e47 |
+ * setup the mapping tree.
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (mapping_tree_init()) {
|
|
|
b69e47 |
+ slapi_log_err(SLAPI_LOG_EMERG, "setup_internal_backends", "Failed to init mapping tree\n");
|
|
|
b69e47 |
+ exit(1);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
add_internal_entries();
|
|
|
b69e47 |
|
|
|
b69e47 |
add_easter_egg_entry();
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
|
|
b69e47 |
index 552d54d..1d9afce 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/main.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/main.c
|
|
|
b69e47 |
@@ -1034,16 +1034,6 @@ main( int argc, char **argv)
|
|
|
b69e47 |
|
|
|
b69e47 |
ps_init_psearch_system(); /* must come before plugin_startall() */
|
|
|
b69e47 |
|
|
|
b69e47 |
- /* Initailize the mapping tree */
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (mapping_tree_init())
|
|
|
b69e47 |
- {
|
|
|
b69e47 |
- slapi_log_err(SLAPI_LOG_EMERG, "main", "Failed to init mapping tree\n");
|
|
|
b69e47 |
- return_value = 1;
|
|
|
b69e47 |
- goto cleanup;
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
-
|
|
|
b69e47 |
/* initialize UniqueID generator - must be done once backends are started
|
|
|
b69e47 |
and event queue is initialized but before plugins are started */
|
|
|
b69e47 |
/* Note: This DN is no need to be normalized. */
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
|
|
|
b69e47 |
index 1b8d2d9..dfb6584 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/mapping_tree.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/mapping_tree.c
|
|
|
b69e47 |
@@ -88,13 +88,13 @@ struct mt_node
|
|
|
b69e47 |
* release backend lock
|
|
|
b69e47 |
*
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
-static Slapi_RWLock *myLock; /* global lock on the mapping tree structures */
|
|
|
b69e47 |
+static Slapi_RWLock *myLock = NULL; /* global lock on the mapping tree structures */
|
|
|
b69e47 |
|
|
|
b69e47 |
|
|
|
b69e47 |
static mapping_tree_node *mapping_tree_root = NULL;
|
|
|
b69e47 |
-static int mapping_tree_inited = 0;
|
|
|
b69e47 |
-static int mapping_tree_freed = 0;
|
|
|
b69e47 |
-static int extension_type = -1; /* type returned from the factory */
|
|
|
b69e47 |
+static int32_t mapping_tree_inited = 0;
|
|
|
b69e47 |
+static int32_t mapping_tree_freed = 0;
|
|
|
b69e47 |
+static int extension_type = -1; /* type returned from the factory */
|
|
|
b69e47 |
|
|
|
b69e47 |
/* The different states a mapping tree node can be in. */
|
|
|
b69e47 |
#define MTN_DISABLED 0 /* The server acts like the node isn't there. */
|
|
|
b69e47 |
@@ -1659,22 +1659,24 @@ add_internal_mapping_tree_node(const char *subtree, Slapi_Backend *be, mapping_t
|
|
|
b69e47 |
{
|
|
|
b69e47 |
Slapi_DN *dn;
|
|
|
b69e47 |
mapping_tree_node *node;
|
|
|
b69e47 |
- backend ** be_list = (backend **) slapi_ch_malloc(sizeof(backend *));
|
|
|
b69e47 |
+ backend **be_list = (backend **)slapi_ch_malloc(sizeof(backend *));
|
|
|
b69e47 |
+ int *be_states = (int *)slapi_ch_malloc(sizeof(int));
|
|
|
b69e47 |
|
|
|
b69e47 |
be_list[0] = be;
|
|
|
b69e47 |
+ be_states[0] = SLAPI_BE_STATE_ON;
|
|
|
b69e47 |
|
|
|
b69e47 |
dn = slapi_sdn_new_dn_byval(subtree);
|
|
|
b69e47 |
- node= mapping_tree_node_new(
|
|
|
b69e47 |
- dn,
|
|
|
b69e47 |
- be_list,
|
|
|
b69e47 |
- NULL, /* backend_name */
|
|
|
b69e47 |
- NULL,
|
|
|
b69e47 |
- 1, /* number of backends at this node */
|
|
|
b69e47 |
- 1, /* size of backend list structure */
|
|
|
b69e47 |
- NULL, /* referral */
|
|
|
b69e47 |
- parent,
|
|
|
b69e47 |
- MTN_BACKEND,
|
|
|
b69e47 |
- 1, /* The config node is a private node.
|
|
|
b69e47 |
+ node = mapping_tree_node_new(
|
|
|
b69e47 |
+ dn,
|
|
|
b69e47 |
+ be_list,
|
|
|
b69e47 |
+ NULL, /* backend_name */
|
|
|
b69e47 |
+ be_states, /* be state */
|
|
|
b69e47 |
+ 1, /* number of backends at this node */
|
|
|
b69e47 |
+ 1, /* size of backend list structure */
|
|
|
b69e47 |
+ NULL, /* referral */
|
|
|
b69e47 |
+ parent,
|
|
|
b69e47 |
+ MTN_BACKEND,
|
|
|
b69e47 |
+ 1, /* The config node is a private node.
|
|
|
b69e47 |
* People can't see or change it. */
|
|
|
b69e47 |
NULL, NULL, NULL, 0); /* no distribution */
|
|
|
b69e47 |
return node;
|
|
|
b69e47 |
@@ -1722,17 +1724,20 @@ mapping_tree_init()
|
|
|
b69e47 |
|
|
|
b69e47 |
/* we call this function from a single thread, so it should be ok */
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
- /* shutdown has been detected */
|
|
|
b69e47 |
- return 0;
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (mapping_tree_inited)
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
+ /* shutdown has been detected */
|
|
|
b69e47 |
return 0;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
|
|
|
b69e47 |
- /* ONREPL - I have moved this up because otherwise we can endup calling this
|
|
|
b69e47 |
+ /* ONREPL - I have moved this up because otherwise we can endup calling this
|
|
|
b69e47 |
* function recursively */
|
|
|
b69e47 |
+ if (myLock != NULL) {
|
|
|
b69e47 |
+ return 0;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ myLock = slapi_new_rwlock();
|
|
|
b69e47 |
+ slapi_rwlock_wrlock(myLock);
|
|
|
b69e47 |
|
|
|
b69e47 |
+ /* Should be fenced by the rwlock. */
|
|
|
b69e47 |
mapping_tree_inited = 1;
|
|
|
b69e47 |
|
|
|
b69e47 |
slapi_register_supported_control(MTN_CONTROL_USE_ONE_BACKEND_OID,
|
|
|
b69e47 |
@@ -1740,10 +1745,8 @@ mapping_tree_init()
|
|
|
b69e47 |
slapi_register_supported_control(MTN_CONTROL_USE_ONE_BACKEND_EXT_OID,
|
|
|
b69e47 |
SLAPI_OPERATION_SEARCH);
|
|
|
b69e47 |
|
|
|
b69e47 |
- myLock = slapi_new_rwlock();
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- be= slapi_be_select_by_instance_name(DSE_BACKEND);
|
|
|
b69e47 |
- mapping_tree_root= add_internal_mapping_tree_node("", be, NULL);
|
|
|
b69e47 |
+ be = slapi_be_select_by_instance_name(DSE_BACKEND);
|
|
|
b69e47 |
+ mapping_tree_root = add_internal_mapping_tree_node("", be, NULL);
|
|
|
b69e47 |
|
|
|
b69e47 |
/* We also need to add the config and schema backends to the mapping tree.
|
|
|
b69e47 |
* They are special in that users will not know about it's node in the
|
|
|
b69e47 |
@@ -1757,17 +1760,23 @@ mapping_tree_init()
|
|
|
b69e47 |
node= add_internal_mapping_tree_node("cn=schema", be, mapping_tree_root);
|
|
|
b69e47 |
mapping_tree_node_add_child(mapping_tree_root, node);
|
|
|
b69e47 |
|
|
|
b69e47 |
- /*
|
|
|
b69e47 |
+ slapi_rwlock_unlock(myLock);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /*
|
|
|
b69e47 |
* Now we need to look under cn=mapping tree, cn=config to find the rest
|
|
|
b69e47 |
* of the mapping tree entries.
|
|
|
b69e47 |
* Builds the mapping tree from entries in the DIT. This function just
|
|
|
b69e47 |
* calls mapping_tree_node_get_children with the special case for the
|
|
|
b69e47 |
* root node.
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
- if (mapping_tree_node_get_children(mapping_tree_root, 1))
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (mapping_tree_node_get_children(mapping_tree_root, 1)) {
|
|
|
b69e47 |
return -1;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
|
|
|
b69e47 |
+ slapi_rwlock_wrlock(myLock);
|
|
|
b69e47 |
mtn_create_extension(mapping_tree_root);
|
|
|
b69e47 |
+ slapi_rwlock_unlock(myLock);
|
|
|
b69e47 |
|
|
|
b69e47 |
/* setup the dse callback functions for the ldbm instance config entry */
|
|
|
b69e47 |
{
|
|
|
b69e47 |
@@ -1840,8 +1849,8 @@ mapping_tree_free ()
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
slapi_unregister_backend_state_change_all();
|
|
|
b69e47 |
/* recursively free tree nodes */
|
|
|
b69e47 |
- mtn_free_node (&mapping_tree_root);
|
|
|
b69e47 |
- mapping_tree_freed = 1;
|
|
|
b69e47 |
+ mtn_free_node(&mapping_tree_root);
|
|
|
b69e47 |
+ __atomic_store_4(&mapping_tree_freed, 1, __ATOMIC_RELAXED);
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
/* This function returns the first node to parse when a search is done
|
|
|
b69e47 |
@@ -2083,14 +2092,12 @@ int slapi_dn_write_needs_referral(Slapi_DN *target_sdn, Slapi_Entry **referral)
|
|
|
b69e47 |
mapping_tree_node *target_node = NULL;
|
|
|
b69e47 |
int ret = 0;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
goto done;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(!mapping_tree_inited) {
|
|
|
b69e47 |
- mapping_tree_init();
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ PR_ASSERT(mapping_tree_inited == 1);
|
|
|
b69e47 |
|
|
|
b69e47 |
if (target_sdn) {
|
|
|
b69e47 |
mtn_lock();
|
|
|
b69e47 |
@@ -2157,8 +2164,8 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
|
|
b69e47 |
int fixup = 0;
|
|
|
b69e47 |
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
- /* shutdown detected */
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
+ /* shutdown detected */
|
|
|
b69e47 |
return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
@@ -2175,9 +2182,7 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
|
|
b69e47 |
target_sdn = operation_get_target_spec (op);
|
|
|
b69e47 |
fixup = operation_is_flag_set(op, OP_FLAG_TOMBSTONE_FIXUP);
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(!mapping_tree_inited) {
|
|
|
b69e47 |
- mapping_tree_init();
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ PR_ASSERT(mapping_tree_inited == 1);
|
|
|
b69e47 |
|
|
|
b69e47 |
be[0] = NULL;
|
|
|
b69e47 |
if (referral) {
|
|
|
b69e47 |
@@ -2188,8 +2193,9 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
|
|
b69e47 |
|
|
|
b69e47 |
/* Get the mapping tree node that is the best match for the target dn. */
|
|
|
b69e47 |
target_node = slapi_get_mapping_tree_node_by_dn(target_sdn);
|
|
|
b69e47 |
- if (target_node == NULL)
|
|
|
b69e47 |
+ if (target_node == NULL) {
|
|
|
b69e47 |
target_node = mapping_tree_root;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
|
|
|
b69e47 |
/* The processing of the base scope root DSE search and all other LDAP operations on ""
|
|
|
b69e47 |
* will be transferred to the internal DSE backend
|
|
|
b69e47 |
@@ -2266,8 +2272,8 @@ int slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list,
|
|
|
b69e47 |
Slapi_DN *sdn = NULL;
|
|
|
b69e47 |
int flag_partial_result = 0;
|
|
|
b69e47 |
int op_type;
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
@@ -2287,9 +2293,7 @@ int slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list,
|
|
|
b69e47 |
slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
|
|
|
b69e47 |
slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &scope);
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(!mapping_tree_inited){
|
|
|
b69e47 |
- mapping_tree_init();
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ PR_ASSERT(mapping_tree_inited == 1);
|
|
|
b69e47 |
|
|
|
b69e47 |
mtn_lock();
|
|
|
b69e47 |
|
|
|
b69e47 |
@@ -2448,8 +2452,8 @@ int slapi_mapping_tree_select_and_check(Slapi_PBlock *pb,char *newdn, Slapi_Back
|
|
|
b69e47 |
Slapi_Operation *op;
|
|
|
b69e47 |
int ret;
|
|
|
b69e47 |
int need_unlock = 0;
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
@@ -2635,7 +2639,7 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
|
|
b69e47 |
int flag_stop = 0;
|
|
|
b69e47 |
struct slapi_componentid *cid = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shut down detected */
|
|
|
b69e47 |
return LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2719,21 +2723,22 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
|
|
b69e47 |
} else {
|
|
|
b69e47 |
/* This MTN has not been linked to its backend
|
|
|
b69e47 |
* instance yet. */
|
|
|
b69e47 |
- target_node->mtn_be[*index] =
|
|
|
b69e47 |
- slapi_be_select_by_instance_name(
|
|
|
b69e47 |
- target_node->mtn_backend_names[*index]);
|
|
|
b69e47 |
- *be = target_node->mtn_be[*index];
|
|
|
b69e47 |
- if(*be==NULL) {
|
|
|
b69e47 |
- slapi_log_err(SLAPI_LOG_BACKLDBM, "mtn_get_be",
|
|
|
b69e47 |
- "Warning: Mapping tree node entry for %s "
|
|
|
b69e47 |
- "point to an unknown backend : %s\n",
|
|
|
b69e47 |
- slapi_sdn_get_dn(target_node->mtn_subtree),
|
|
|
b69e47 |
- target_node->mtn_backend_names[*index]);
|
|
|
b69e47 |
- /* Well there's still not backend instance for
|
|
|
b69e47 |
- * this MTN, so let's have the default backend
|
|
|
b69e47 |
- * deal with this.
|
|
|
b69e47 |
- */
|
|
|
b69e47 |
- *be = defbackend_get_backend();
|
|
|
b69e47 |
+ /* WARNING: internal memory dse backends don't provide NAMES */
|
|
|
b69e47 |
+ if (target_node->mtn_backend_names != NULL) {
|
|
|
b69e47 |
+ target_node->mtn_be[*index] = slapi_be_select_by_instance_name(target_node->mtn_backend_names[*index]);
|
|
|
b69e47 |
+ *be = target_node->mtn_be[*index];
|
|
|
b69e47 |
+ if (*be == NULL) {
|
|
|
b69e47 |
+ slapi_log_err(SLAPI_LOG_BACKLDBM, "mtn_get_be",
|
|
|
b69e47 |
+ "Warning: Mapping tree node entry for %s "
|
|
|
b69e47 |
+ "point to an unknown backend : %s\n",
|
|
|
b69e47 |
+ slapi_sdn_get_dn(target_node->mtn_subtree),
|
|
|
b69e47 |
+ target_node->mtn_backend_names[*index]);
|
|
|
b69e47 |
+ /* Well there's still not backend instance for
|
|
|
b69e47 |
+ * this MTN, so let's have the default backend
|
|
|
b69e47 |
+ * deal with this.
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+ *be = defbackend_get_backend();
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
}
|
|
|
b69e47 |
}
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2745,10 +2750,11 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
|
|
b69e47 |
result = LDAP_OPERATIONS_ERROR;
|
|
|
b69e47 |
*be = defbackend_get_backend();
|
|
|
b69e47 |
}
|
|
|
b69e47 |
- if (flag_stop)
|
|
|
b69e47 |
+ if (flag_stop) {
|
|
|
b69e47 |
*index = SLAPI_BE_NO_BACKEND;
|
|
|
b69e47 |
- else
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
(*index)++;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
}
|
|
|
b69e47 |
}
|
|
|
b69e47 |
} else {
|
|
|
b69e47 |
@@ -2822,7 +2828,7 @@ static mapping_tree_node *best_matching_child(mapping_tree_node *parent,
|
|
|
b69e47 |
mapping_tree_node *highest_match_node = NULL;
|
|
|
b69e47 |
mapping_tree_node *current;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2849,7 +2855,7 @@ mtn_get_mapping_tree_node_by_entry(mapping_tree_node* node, const Slapi_DN *dn)
|
|
|
b69e47 |
{
|
|
|
b69e47 |
mapping_tree_node *found_node = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2895,7 +2901,7 @@ slapi_get_mapping_tree_node_by_dn(const Slapi_DN *dn)
|
|
|
b69e47 |
mapping_tree_node *current_best_match = mapping_tree_root;
|
|
|
b69e47 |
mapping_tree_node *next_best_match = mapping_tree_root;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2929,7 +2935,7 @@ get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name)
|
|
|
b69e47 |
int i;
|
|
|
b69e47 |
mapping_tree_node *found_node = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -2980,7 +2986,7 @@ slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
|
|
|
b69e47 |
{
|
|
|
b69e47 |
char *dn = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
@@ -3007,7 +3013,7 @@ slapi_get_mapping_tree_node_configsdn (const Slapi_DN *root)
|
|
|
b69e47 |
char *dn = NULL;
|
|
|
b69e47 |
Slapi_DN *sdn = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if(mapping_tree_freed){
|
|
|
b69e47 |
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
|
|
b69e47 |
/* shutdown detected */
|
|
|
b69e47 |
return NULL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
index cb182ed..1f0c18a 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/pw_verify.c
|
|
|
b69e47 |
@@ -58,12 +58,14 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
|
|
b69e47 |
int rc = SLAPI_BIND_SUCCESS;
|
|
|
b69e47 |
Slapi_Backend *be = NULL;
|
|
|
b69e47 |
|
|
|
b69e47 |
- if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
|
|
b69e47 |
+ int mt_result = slapi_mapping_tree_select(pb, &be, referral, NULL, 0);
|
|
|
b69e47 |
+ if (mt_result != LDAP_SUCCESS) {
|
|
|
b69e47 |
return SLAPI_BIND_NO_BACKEND;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
if (*referral) {
|
|
|
b69e47 |
- slapi_be_Unlock(be);
|
|
|
b69e47 |
+ /* If we have a referral, this is NULL */
|
|
|
b69e47 |
+ PR_ASSERT(be == NULL);
|
|
|
b69e47 |
return SLAPI_BIND_REFERRAL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
@@ -128,7 +130,7 @@ pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
if (*referral) {
|
|
|
b69e47 |
- slapi_be_Unlock(be);
|
|
|
b69e47 |
+ PR_ASSERT(be == NULL);
|
|
|
b69e47 |
return SLAPI_BIND_REFERRAL;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
--
|
|
|
b69e47 |
2.9.4
|
|
|
b69e47 |
|