mirror of
https://git.centos.org/rpms/389-ds-base.git
synced 2025-02-23 16:22:54 +00:00
import 389-ds-base-1.3.8.4-15.el7
This commit is contained in:
parent
6e88154da0
commit
edc5f25778
108 changed files with 811 additions and 22605 deletions
|
@ -1 +1 @@
|
|||
77dee99c82e77c3c3c8579b443ebb68e63d51702 SOURCES/389-ds-base-1.3.7.5.tar.bz2
|
||||
930c13abb2fc444f1dbd0443ed72a5d5b14c48da SOURCES/389-ds-base-1.3.8.4.tar.bz2
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1 @@
|
|||
SOURCES/389-ds-base-1.3.7.5.tar.bz2
|
||||
SOURCES/389-ds-base-1.3.8.4.tar.bz2
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,190 @@
|
|||
From da5a1bbb4e4352b8df10c84572441d47217b6c2c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 6 Jul 2018 11:37:56 -0400
|
||||
Subject: [PATCH] Ticket 49830 - Import fails if backend name is "default"
|
||||
|
||||
Bug Description: The server was previously reserving the backend
|
||||
name "default". If you tried to import on a
|
||||
backend with this name the import would skip all
|
||||
child entries
|
||||
|
||||
Fix Description: Change the default backend name to something
|
||||
obscure, instead of "default".
|
||||
|
||||
Also improved lib389's dbgen to generate the
|
||||
correct "dc" attribute value in the root node.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49830
|
||||
|
||||
Reviewed by: spichugi(Thanks!)
|
||||
|
||||
(cherry picked from commit 8fa838a4ffd4d0c15ae51cb21f246bb1f2dea2a1)
|
||||
---
|
||||
.../tests/suites/import/regression_test.py | 46 +++++++++++++++++++
|
||||
ldap/servers/slapd/defbackend.c | 4 +-
|
||||
ldap/servers/slapd/mapping_tree.c | 7 ++-
|
||||
ldap/servers/slapd/slap.h | 3 ++
|
||||
src/lib389/lib389/dbgen.py | 13 +++++-
|
||||
5 files changed, 66 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/import/regression_test.py b/dirsrvtests/tests/suites/import/regression_test.py
|
||||
index ad51721a1..d83d00323 100644
|
||||
--- a/dirsrvtests/tests/suites/import/regression_test.py
|
||||
+++ b/dirsrvtests/tests/suites/import/regression_test.py
|
||||
@@ -23,6 +23,52 @@ TEST_SUFFIX1 = "dc=importest1,dc=com"
|
||||
TEST_BACKEND1 = "importest1"
|
||||
TEST_SUFFIX2 = "dc=importest2,dc=com"
|
||||
TEST_BACKEND2 = "importest2"
|
||||
+TEST_DEFAULT_SUFFIX = "dc=default,dc=com"
|
||||
+TEST_DEFAULT_NAME = "default"
|
||||
+
|
||||
+
|
||||
+def test_import_be_default(topo):
|
||||
+ """ Create a backend using the name "default". previously this name was
|
||||
+ used int
|
||||
+
|
||||
+ :id: 8e507beb-e917-4330-8cac-1ff0eee10508
|
||||
+ :feature: Import
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1. Create a test suffix using the be name of "default"
|
||||
+ 2. Create an ldif for the "default" backend
|
||||
+ 3. Import ldif
|
||||
+ 4. Verify all entries were imported
|
||||
+ :expectedresults:
|
||||
+ 1. Success
|
||||
+ 2. Success
|
||||
+ 3. Success
|
||||
+ 4. Success
|
||||
+ """
|
||||
+ log.info('Adding suffix:{} and backend: {}...'.format(TEST_DEFAULT_SUFFIX,
|
||||
+ TEST_DEFAULT_NAME))
|
||||
+ backends = Backends(topo.standalone)
|
||||
+ backends.create(properties={BACKEND_SUFFIX: TEST_DEFAULT_SUFFIX,
|
||||
+ BACKEND_NAME: TEST_DEFAULT_NAME})
|
||||
+
|
||||
+ log.info('Create LDIF file and import it...')
|
||||
+ ldif_dir = topo.standalone.get_ldif_dir()
|
||||
+ ldif_file = os.path.join(ldif_dir, 'default.ldif')
|
||||
+ dbgen(topo.standalone, 5, ldif_file, TEST_DEFAULT_SUFFIX)
|
||||
+
|
||||
+ log.info('Stopping the server and running offline import...')
|
||||
+ topo.standalone.stop()
|
||||
+ assert topo.standalone.ldif2db(TEST_DEFAULT_NAME, None, None,
|
||||
+ None, ldif_file)
|
||||
+ topo.standalone.start()
|
||||
+
|
||||
+ log.info('Verifying entry count after import...')
|
||||
+ entries = topo.standalone.search_s(TEST_DEFAULT_SUFFIX,
|
||||
+ ldap.SCOPE_SUBTREE,
|
||||
+ "(objectclass=*)")
|
||||
+ assert len(entries) > 1
|
||||
+
|
||||
+ log.info('Test PASSED')
|
||||
|
||||
|
||||
def test_del_suffix_import(topo):
|
||||
diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c
|
||||
index aa709da87..b0465e297 100644
|
||||
--- a/ldap/servers/slapd/defbackend.c
|
||||
+++ b/ldap/servers/slapd/defbackend.c
|
||||
@@ -23,8 +23,6 @@
|
||||
/*
|
||||
* ---------------- Macros ---------------------------------------------------
|
||||
*/
|
||||
-#define DEFBACKEND_TYPE "default"
|
||||
-
|
||||
#define DEFBACKEND_OP_NOT_HANDLED 0
|
||||
#define DEFBACKEND_OP_HANDLED 1
|
||||
|
||||
@@ -65,7 +63,7 @@ defbackend_init(void)
|
||||
/*
|
||||
* create a new backend
|
||||
*/
|
||||
- defbackend_backend = slapi_be_new(DEFBACKEND_TYPE, DEFBACKEND_TYPE, 1 /* Private */, 0 /* Do Not Log Changes */);
|
||||
+ defbackend_backend = slapi_be_new(DEFBACKEND_TYPE, DEFBACKEND_NAME, 1 /* Private */, 0 /* Do Not Log Changes */);
|
||||
if ((rc = slapi_pblock_set(pb, SLAPI_BACKEND, defbackend_backend)) != 0) {
|
||||
errmsg = "slapi_pblock_set SLAPI_BACKEND failed";
|
||||
goto cleanup_and_return;
|
||||
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
|
||||
index 472a2f6aa..834949a67 100644
|
||||
--- a/ldap/servers/slapd/mapping_tree.c
|
||||
+++ b/ldap/servers/slapd/mapping_tree.c
|
||||
@@ -748,7 +748,7 @@ mapping_tree_entry_add(Slapi_Entry *entry, mapping_tree_node **newnodep)
|
||||
be_names = (char **)slapi_ch_calloc(1, sizeof(char *));
|
||||
be_states = (int *)slapi_ch_calloc(1, sizeof(int));
|
||||
|
||||
- tmp_backend_name = (char *)slapi_ch_strdup("default"); /* "NULL_CONTAINER" */
|
||||
+ tmp_backend_name = (char *)slapi_ch_strdup(DEFBACKEND_NAME); /* "NULL_CONTAINER" */
|
||||
(be_names)[be_list_count] = tmp_backend_name;
|
||||
|
||||
/* set backend as started by default */
|
||||
@@ -2250,7 +2250,10 @@ slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list, Slapi_E
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
/* flag we have problems at least on part of the tree */
|
||||
flag_partial_result = 1;
|
||||
- } else if ((((!slapi_sdn_issuffix(sdn, slapi_mtn_get_dn(node)) && !slapi_sdn_issuffix(slapi_mtn_get_dn(node), sdn))) || ((node_list == mapping_tree_root) && node->mtn_private && (scope != LDAP_SCOPE_BASE))) && (!be || strncmp(be->be_name, "default", 8))) {
|
||||
+ } else if ((((!slapi_sdn_issuffix(sdn, slapi_mtn_get_dn(node)) && !slapi_sdn_issuffix(slapi_mtn_get_dn(node), sdn))) ||
|
||||
+ ((node_list == mapping_tree_root) && node->mtn_private && (scope != LDAP_SCOPE_BASE))) &&
|
||||
+ (!be || strncmp(be->be_name, DEFBACKEND_NAME, 8)))
|
||||
+ {
|
||||
if (be && !be_isdeleted(be)) {
|
||||
/* wrong backend or referall, ignore it */
|
||||
slapi_log_err(SLAPI_LOG_ARGS, "slapi_mapping_tree_select_all",
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 7378c2d2a..eb97cdcc4 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -45,6 +45,9 @@ static char ptokPBE[34] = "Internal (Software) Token ";
|
||||
#define SLAPD_EXEMODE_DBVERIFY 12
|
||||
#define SLAPD_EXEMODE_UPGRADEDNFORMAT 13
|
||||
|
||||
+#define DEFBACKEND_TYPE "default"
|
||||
+#define DEFBACKEND_NAME "DirectoryServerDefaultBackend"
|
||||
+
|
||||
#define LDAP_SYSLOG
|
||||
#include <syslog.h>
|
||||
#define RLIM_TYPE int
|
||||
diff --git a/src/lib389/lib389/dbgen.py b/src/lib389/lib389/dbgen.py
|
||||
index a0cda9430..68455b480 100644
|
||||
--- a/src/lib389/lib389/dbgen.py
|
||||
+++ b/src/lib389/lib389/dbgen.py
|
||||
@@ -113,8 +113,13 @@ usercertificate;binary:: MIIBvjCCASegAwIBAgIBAjANBgkqhkiG9w0BAQQFADAnMQ8wDQYD
|
||||
DBGEN_HEADER = """dn: {SUFFIX}
|
||||
objectClass: top
|
||||
objectClass: domain
|
||||
+<<<<<<< HEAD
|
||||
dc: example
|
||||
aci: (target=ldap:///{SUFFIX})(targetattr=*)(version 3.0; acl "acl1"; allow(write) userdn = "ldap:///self";)
|
||||
+=======
|
||||
+dc: {RDN}
|
||||
+aci: (target=ldap:///{SUFFIX})(targetattr=*)(version 3.0; acl "acl1"; allow(write) userdn = "ldap:///self";)
|
||||
+>>>>>>> 8fa838a4f... Ticket 49830 - Import fails if backend name is "default"
|
||||
aci: (target=ldap:///{SUFFIX})(targetattr=*)(version 3.0; acl "acl2"; allow(write) groupdn = "ldap:///cn=Directory Administrators, {SUFFIX}";)
|
||||
aci: (target=ldap:///{SUFFIX})(targetattr=*)(version 3.0; acl "acl3"; allow(read, search, compare) userdn = "ldap:///anyone";)
|
||||
|
||||
@@ -145,7 +150,7 @@ ou: Payroll
|
||||
|
||||
"""
|
||||
|
||||
-def dbgen(instance, number, ldif_file, suffix):
|
||||
+def dbgen(instance, number, ldif_file, suffix, pseudol10n=False):
|
||||
familyname_file = os.path.join(instance.ds_paths.data_dir, 'dirsrv/data/dbgen-FamilyNames')
|
||||
givename_file = os.path.join(instance.ds_paths.data_dir, 'dirsrv/data/dbgen-GivenNames')
|
||||
familynames = []
|
||||
@@ -156,7 +161,11 @@ def dbgen(instance, number, ldif_file, suffix):
|
||||
givennames = [n.strip() for n in f]
|
||||
|
||||
with open(ldif_file, 'w') as output:
|
||||
- output.write(DBGEN_HEADER.format(SUFFIX=suffix))
|
||||
+ rdn = suffix.split(",", 1)[0].split("=", 1)[1]
|
||||
+ output.write(DBGEN_HEADER.format(SUFFIX=suffix, RDN=rdn))
|
||||
+ for ou in DBGEN_OUS:
|
||||
+ ou = pseudolocalize(ou) if pseudol10n else ou
|
||||
+ output.write(DBGEN_OU_TEMPLATE.format(SUFFIX=suffix, OU=ou))
|
||||
for i in range(0, number):
|
||||
# Pick a random ou
|
||||
ou = random.choice(DBGEN_OUS)
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 0ea14f45cbc834e4791fdc393c5a2a042fd08101 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Tue, 10 Jul 2018 12:07:45 +0200
|
||||
Subject: [PATCH] Ticket 48818 - For a replica bindDNGroup, should be fetched
|
||||
the first time it is used not when the replica is started
|
||||
|
||||
Bug Description:
|
||||
The fetching of the bindDNGroup is working as designed but this ticket is to make it more flexible
|
||||
|
||||
At startup, if the group does not contain the replica_mgr.
|
||||
No replication session will succeed until bindDnGroupCheckInterval delay.
|
||||
updatedn_group_last_check is the timestamp of the last fetch. At startup
|
||||
updatedn_group_last_check is set to the current time. So the next fetch will happen not before
|
||||
updatedn_group_last_check+bindDnGroupCheckInterval.
|
||||
|
||||
If the groupDn is changed after startup, no incoming replication can happen for the first
|
||||
bindDnGroupCheckInterval seconds
|
||||
|
||||
Fix Description:
|
||||
The fix consist to unset updatedn_group_last_check so that the group will be fetch when the first
|
||||
incoming replication session will happen.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49818
|
||||
|
||||
Reviewed by: Mark Reynolds, Simon Spichugi (thanks !!!)
|
||||
|
||||
Platforms tested: F27
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index dee20875e..41cad3bf0 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -2026,7 +2026,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
|
||||
/* get replication bind dn groups */
|
||||
r->updatedn_groups = replica_updatedn_group_new(e);
|
||||
r->groupdn_list = replica_groupdn_list_new(r->updatedn_groups);
|
||||
- r->updatedn_group_last_check = time(NULL);
|
||||
+ r->updatedn_group_last_check = 0;
|
||||
/* get groupdn check interval */
|
||||
if ((val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval))) {
|
||||
if (repl_config_valid_num(attr_replicaBindDnGroupCheckInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) {
|
||||
--
|
||||
2.17.1
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,286 +0,0 @@
|
|||
From 8308e20075adacfdf1827aaa3230e503207832bc Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 2 Oct 2017 09:33:29 -0400
|
||||
Subject: [PATCH] Ticket 49385 - Fix coverity warnings
|
||||
|
||||
Description: This fixes coverity issues found from RHEL build of 1.3.7
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49385
|
||||
|
||||
Reviewed by: lkrispenz(Thanks!)
|
||||
|
||||
(cherry picked from commit 805e8f4d3016eb9c7906c1416482047a234d51ba)
|
||||
---
|
||||
ldap/servers/plugins/http/http_impl.c | 1 +
|
||||
ldap/servers/plugins/replication/urp.c | 10 ++++++----
|
||||
ldap/servers/plugins/syntaxes/string.c | 1 +
|
||||
ldap/servers/slapd/back-ldbm/dbversion.c | 2 +-
|
||||
ldap/servers/slapd/back-ldbm/index.c | 1 +
|
||||
ldap/servers/slapd/conntable.c | 2 +-
|
||||
ldap/servers/slapd/modify.c | 1 +
|
||||
ldap/servers/slapd/plugin.c | 3 ++-
|
||||
ldap/servers/slapd/referral.c | 18 +++++++++---------
|
||||
ldap/servers/slapd/task.c | 8 ++++++--
|
||||
ldap/servers/snmp/main.c | 13 +++++++++++--
|
||||
11 files changed, 40 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/http/http_impl.c b/ldap/servers/plugins/http/http_impl.c
|
||||
index d8bbe38..350c839 100644
|
||||
--- a/ldap/servers/plugins/http/http_impl.c
|
||||
+++ b/ldap/servers/plugins/http/http_impl.c
|
||||
@@ -601,6 +601,7 @@ sendPostReq(PRFileDesc *fd, const char *path, httpheader **httpheaderArray, char
|
||||
if (path) {
|
||||
path_len = strlen(path);
|
||||
} else {
|
||||
+ path = "";
|
||||
path_len = 0;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c
|
||||
index 3d63c64..9534c03 100644
|
||||
--- a/ldap/servers/plugins/replication/urp.c
|
||||
+++ b/ldap/servers/plugins/replication/urp.c
|
||||
@@ -856,7 +856,7 @@ urp_post_delete_operation(Slapi_PBlock *pb)
|
||||
static int
|
||||
urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
{
|
||||
- Slapi_PBlock *add_pb = slapi_pblock_new();
|
||||
+ Slapi_PBlock *add_pb;
|
||||
Slapi_Entry *cenotaph = NULL;
|
||||
Slapi_Entry *pre_entry = NULL;
|
||||
int ret = 0;
|
||||
@@ -886,6 +886,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
slapi_rdn_remove_attr (rdn, SLAPI_ATTR_UNIQUEID );
|
||||
slapi_rdn_add(rdn, "cenotaphID", uniqueid);
|
||||
newdn = slapi_ch_smprintf("%s,%s", slapi_rdn_get_rdn(rdn), parentdn);
|
||||
+ slapi_rdn_free(&rdn);
|
||||
slapi_ch_free_string(&parentdn);
|
||||
/* slapi_sdn_free(&pre_sdn); */
|
||||
|
||||
@@ -902,6 +903,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
|
||||
slapi_log_err(SLAPI_LOG_REPL, sessionid,
|
||||
"urp_fixup_add_cenotaph - addinng cenotaph: %s \n", newdn);
|
||||
+ add_pb = slapi_pblock_new();
|
||||
slapi_pblock_init(add_pb);
|
||||
|
||||
slapi_add_entry_internal_set_pb(add_pb,
|
||||
@@ -1661,8 +1663,8 @@ urp_conflict_to_glue (char *sessionid, const Slapi_Entry *entry, Slapi_DN *paren
|
||||
"urp_conflict_to_glue failed(%d) - %s --> %s\n", op_result, basedn, newrdn);
|
||||
rc = 1;
|
||||
}
|
||||
- slapi_ch_free ( (void**)&newrdn );
|
||||
}
|
||||
+ slapi_rdn_free(&parentrdn);
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
@@ -2166,11 +2168,11 @@ mod_objectclass_attr(const char *uniqueid, const Slapi_DN *entrysdn, const Slapi
|
||||
{
|
||||
Slapi_Mods smods;
|
||||
int op_result;
|
||||
- char csnstr[CSN_STRSIZE+1];
|
||||
+ char csnstr[CSN_STRSIZE+1] = {0};
|
||||
|
||||
slapi_mods_init(&smods, 3);
|
||||
slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry");
|
||||
- slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr),csn_as_string(opcsn, PR_FALSE, csnstr));
|
||||
+ slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", CSN_STRSIZE, csn_as_string(opcsn, PR_FALSE, csnstr));
|
||||
op_result = urp_fixup_modify_entry(uniqueid, entrysdn, opcsn, &smods, 0);
|
||||
slapi_mods_done(&smods);
|
||||
if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
|
||||
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
|
||||
index f50dc13..e05ca7f 100644
|
||||
--- a/ldap/servers/plugins/syntaxes/string.c
|
||||
+++ b/ldap/servers/plugins/syntaxes/string.c
|
||||
@@ -391,6 +391,7 @@ bailout:
|
||||
if (free_re) {
|
||||
slapi_re_free(re);
|
||||
}
|
||||
+ slapi_ch_free_string(&alt);
|
||||
slapi_ch_free((void **)&tmpbuf); /* NULL is fine */
|
||||
slapi_ch_free((void **)&bigpat); /* NULL is fine */
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/dbversion.c b/ldap/servers/slapd/back-ldbm/dbversion.c
|
||||
index 01f86f4..5a77abd 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dbversion.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dbversion.c
|
||||
@@ -159,7 +159,7 @@ dbversion_read(struct ldbminfo *li, const char *directory, char **ldbmversion, c
|
||||
}
|
||||
(void)PR_Close(prfd);
|
||||
|
||||
- if (*dataversion == NULL) {
|
||||
+ if (dataversion == NULL || *dataversion == NULL) {
|
||||
slapi_log_err(SLAPI_LOG_DEBUG, "dbversion_read", "dataversion not present in \"%s\"\n", filename);
|
||||
}
|
||||
if (*ldbmversion == NULL) {
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
|
||||
index 798480e..58b11ed 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/index.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/index.c
|
||||
@@ -1063,6 +1063,7 @@ index_read_ext_allids(
|
||||
/* The database might not exist. We have to assume it means empty set */
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "Failed to access idl index for %s\n", basetype);
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "Assuming %s has no index values\n", basetype);
|
||||
+ idl_free(&idl);
|
||||
idl = idl_alloc(0);
|
||||
break;
|
||||
} else {
|
||||
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||
index c04ca0f..7c57b47 100644
|
||||
--- a/ldap/servers/slapd/conntable.c
|
||||
+++ b/ldap/servers/slapd/conntable.c
|
||||
@@ -347,7 +347,7 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e)
|
||||
|
||||
PR_EnterMonitor(ct->c[i].c_mutex);
|
||||
if (ct->c[i].c_sd != SLAPD_INVALID_SOCKET) {
|
||||
- char buf2[20];
|
||||
+ char buf2[SLAPI_TIMESTAMP_BUFSIZE+1];
|
||||
size_t lendn = ct->c[i].c_dn ? strlen(ct->c[i].c_dn) : 6; /* "NULLDN" */
|
||||
size_t lenip = ct->c[i].c_ipaddr ? strlen(ct->c[i].c_ipaddr) : 0;
|
||||
size_t lenconn = 1;
|
||||
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
|
||||
index 4b5a676..6309975 100644
|
||||
--- a/ldap/servers/slapd/modify.c
|
||||
+++ b/ldap/servers/slapd/modify.c
|
||||
@@ -923,6 +923,7 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
|
||||
if (pw_encodevals_ext(pb, sdn, va)) {
|
||||
slapi_log_err(SLAPI_LOG_CRIT, "op_shared_modify", "Unable to hash userPassword attribute for %s.\n", slapi_entry_get_dn_const(e));
|
||||
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Unable to store attribute \"userPassword\" correctly\n", 0, NULL);
|
||||
+ valuearray_free(&va);
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
|
||||
index f47ff9b..e02133a 100644
|
||||
--- a/ldap/servers/slapd/plugin.c
|
||||
+++ b/ldap/servers/slapd/plugin.c
|
||||
@@ -4242,7 +4242,7 @@ bail:
|
||||
int
|
||||
slapi_set_plugin_default_config(const char *type, Slapi_Value *value)
|
||||
{
|
||||
- Slapi_PBlock *pb = slapi_pblock_new();
|
||||
+ Slapi_PBlock *pb;
|
||||
Slapi_Entry **entries = NULL;
|
||||
int rc = LDAP_SUCCESS;
|
||||
char **search_attrs = NULL; /* used by search */
|
||||
@@ -4251,6 +4251,7 @@ slapi_set_plugin_default_config(const char *type, Slapi_Value *value)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+ pb = slapi_pblock_new();
|
||||
charray_add(&search_attrs, slapi_ch_strdup(type));
|
||||
|
||||
/* cn=plugin default config,cn=config */
|
||||
diff --git a/ldap/servers/slapd/referral.c b/ldap/servers/slapd/referral.c
|
||||
index c5d9ffc..5935820 100644
|
||||
--- a/ldap/servers/slapd/referral.c
|
||||
+++ b/ldap/servers/slapd/referral.c
|
||||
@@ -153,7 +153,7 @@ referrals_free(void)
|
||||
struct berval **
|
||||
ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int is_reference)
|
||||
{
|
||||
- int i, len, scope;
|
||||
+ int i, len, scope = 0;
|
||||
Slapi_DN *sdn = NULL;
|
||||
char *p, *opdn_norm;
|
||||
struct berval **urlscopy;
|
||||
@@ -195,9 +195,9 @@ ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int i
|
||||
|
||||
for (i = 0; urls[i] != NULL; ++i) {
|
||||
/*
|
||||
- * duplicate the URL, stripping off the label if there is one and
|
||||
- * leaving extra room for "??base" in case we need to append that.
|
||||
- */
|
||||
+ * duplicate the URL, stripping off the label if there is one and
|
||||
+ * leaving extra room for "??base" in case we need to append that.
|
||||
+ */
|
||||
urlscopy[i] = (struct berval *)slapi_ch_malloc(
|
||||
sizeof(struct berval));
|
||||
if ((p = strchr(urls[i]->bv_val, ' ')) == NULL) {
|
||||
@@ -210,16 +210,16 @@ ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int i
|
||||
urlscopy[i]->bv_val[len] = '\0';
|
||||
|
||||
/*
|
||||
- * adjust the baseDN as needed and set the length
|
||||
- */
|
||||
+ * adjust the baseDN as needed and set the length
|
||||
+ */
|
||||
adjust_referral_basedn(&urlscopy[i]->bv_val, refsdn,
|
||||
opdn_norm, is_reference);
|
||||
urlscopy[i]->bv_len = strlen(urlscopy[i]->bv_val);
|
||||
|
||||
/*
|
||||
- * if we are dealing with a continuation reference that resulted
|
||||
- * from a one-level search, add a scope of base to the URL.
|
||||
- */
|
||||
+ * if we are dealing with a continuation reference that resulted
|
||||
+ * from a one-level search, add a scope of base to the URL.
|
||||
+ */
|
||||
if (is_reference && operation_get_type(op) == SLAPI_OPERATION_SEARCH &&
|
||||
scope == LDAP_SCOPE_ONELEVEL) {
|
||||
strcat(urlscopy[i]->bv_val, "??base");
|
||||
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
|
||||
index f3d02d9..53a0af5 100644
|
||||
--- a/ldap/servers/slapd/task.c
|
||||
+++ b/ldap/servers/slapd/task.c
|
||||
@@ -278,6 +278,10 @@ slapi_task_log_notice(Slapi_Task *task, char *format, ...)
|
||||
char buffer[LOG_BUFFER];
|
||||
size_t len;
|
||||
|
||||
+ if (task == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
va_start(ap, format);
|
||||
PR_vsnprintf(buffer, LOG_BUFFER, format, ap);
|
||||
va_end(ap);
|
||||
@@ -1089,11 +1093,11 @@ task_export_thread(void *arg)
|
||||
slapi_pblock_get(pb, SLAPI_BACKEND_TASK, &task);
|
||||
|
||||
g_incr_active_threadcnt();
|
||||
- for (count = 0, inp = instance_names; *inp; inp++, count++)
|
||||
+ for (count = 0, inp = instance_names; inp && *inp; inp++, count++)
|
||||
;
|
||||
slapi_task_begin(task, count);
|
||||
|
||||
- for (inp = instance_names; *inp; inp++) {
|
||||
+ for (inp = instance_names; inp && *inp; inp++) {
|
||||
int release_me = 0;
|
||||
/* lookup the backend */
|
||||
be = slapi_be_select_by_instance_name((const char *)*inp);
|
||||
diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c
|
||||
index 8477831..5bd318d 100644
|
||||
--- a/ldap/servers/snmp/main.c
|
||||
+++ b/ldap/servers/snmp/main.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ldap.h"
|
||||
#include "ldif.h"
|
||||
#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
|
||||
static char *agentx_master = NULL;
|
||||
static char *agent_logdir = NULL;
|
||||
@@ -54,9 +55,17 @@ main(int argc, char *argv[])
|
||||
{
|
||||
char *s = getenv("DEBUG_SLEEP");
|
||||
if ((s != NULL) && isdigit(*s)) {
|
||||
- int secs = atoi(s);
|
||||
+ char *endp = NULL;
|
||||
+ long secs;
|
||||
+ errno = 0;
|
||||
+
|
||||
printf("%s pid is %d\n", argv[0], getpid());
|
||||
- sleep(secs);
|
||||
+ secs = strtol(s, &endp, 10);
|
||||
+ if (*endp != '\0' || errno == ERANGE) {
|
||||
+ sleep(10);
|
||||
+ } else {
|
||||
+ sleep(secs);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
178
SOURCES/0002-Ticket-49546-Fix-issues-with-MIB-file.patch
Normal file
178
SOURCES/0002-Ticket-49546-Fix-issues-with-MIB-file.patch
Normal file
|
@ -0,0 +1,178 @@
|
|||
From 9f1bbff43c3e6ec01e60d35082b21b83a8795dc2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 12 Jul 2018 10:48:11 -0400
|
||||
Subject: [PATCH] Ticket 49546 - Fix issues with MIB file
|
||||
|
||||
Description: Change dsMaxThreadsHit to dsMaxThreadsHits, and set the
|
||||
proper object type for dsIntIndex
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49546
|
||||
|
||||
Reviewed by: spichugi & firstyear(Thanks!!)
|
||||
|
||||
(cherry picked from commit 6d4caac04be4223971de54d292db82734f6d6a44)
|
||||
---
|
||||
ldap/servers/slapd/agtmmap.c | 2 +-
|
||||
ldap/servers/slapd/agtmmap.h | 2 +-
|
||||
ldap/servers/slapd/connection.c | 2 +-
|
||||
ldap/servers/slapd/slap.h | 2 +-
|
||||
ldap/servers/slapd/snmp_collator.c | 6 +++---
|
||||
ldap/servers/snmp/ldap-agent.c | 4 ++--
|
||||
ldap/servers/snmp/ldap-agent.h | 2 +-
|
||||
ldap/servers/snmp/redhat-directory.mib | 8 ++++----
|
||||
8 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/agtmmap.c b/ldap/servers/slapd/agtmmap.c
|
||||
index fbc730db6..352ccefda 100644
|
||||
--- a/ldap/servers/slapd/agtmmap.c
|
||||
+++ b/ldap/servers/slapd/agtmmap.c
|
||||
@@ -298,7 +298,7 @@ agt_mread_stats(int hdl, struct hdr_stats_t *pHdrInfo, struct ops_stats_t *pDsOp
|
||||
pDsOpsTbl->dsErrors = pfile_stats->ops_stats.dsErrors;
|
||||
pDsOpsTbl->dsConnections = pfile_stats->ops_stats.dsConnections;
|
||||
pDsOpsTbl->dsConnectionsInMaxThreads = pfile_stats->ops_stats.dsConnectionsInMaxThreads;
|
||||
- pDsOpsTbl->dsMaxThreadsHit = pfile_stats->ops_stats.dsMaxThreadsHit;
|
||||
+ pDsOpsTbl->dsMaxThreadsHits = pfile_stats->ops_stats.dsMaxThreadsHits;
|
||||
}
|
||||
|
||||
if (pDsEntTbl != NULL) {
|
||||
diff --git a/ldap/servers/slapd/agtmmap.h b/ldap/servers/slapd/agtmmap.h
|
||||
index 2397dad3c..fb27ab2c4 100644
|
||||
--- a/ldap/servers/slapd/agtmmap.h
|
||||
+++ b/ldap/servers/slapd/agtmmap.h
|
||||
@@ -102,7 +102,7 @@ struct ops_stats_t
|
||||
uint64_t dsErrors;
|
||||
uint64_t dsConnections; /* Number of currently connected clients */
|
||||
uint64_t dsConnectionSeq; /* Monotonically increasing number bumped on each new conn est */
|
||||
- uint64_t dsMaxThreadsHit; /* Number of times a connection hit max threads */
|
||||
+ uint64_t dsMaxThreadsHits; /* Number of times a connection hit max threads */
|
||||
uint64_t dsConnectionsInMaxThreads; /* current number of connections that are in max threads */
|
||||
uint64_t dsBytesRecv; /* Count of bytes read from clients */
|
||||
uint64_t dsBytesSent; /* Count of bytes sent to clients */
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 1dbb49f06..188383b97 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -1911,7 +1911,7 @@ connection_activity(Connection *conn, int maxthreads)
|
||||
slapi_counter_increment(max_threads_count);
|
||||
slapi_counter_increment(conns_in_maxthreads);
|
||||
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsConnectionsInMaxThreads);
|
||||
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHit);
|
||||
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHits);
|
||||
}
|
||||
op_stack_obj = connection_get_operation();
|
||||
connection_add_operation(conn, op_stack_obj->op);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index eb97cdcc4..a02792648 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1889,7 +1889,7 @@ struct snmp_ops_tbl_t
|
||||
Slapi_Counter *dsBytesSent; /* Count of bytes sent to clients */
|
||||
Slapi_Counter *dsEntriesReturned;
|
||||
Slapi_Counter *dsReferralsReturned;
|
||||
- Slapi_Counter *dsMaxThreadsHit;
|
||||
+ Slapi_Counter *dsMaxThreadsHits;
|
||||
Slapi_Counter *dsConnectionsInMaxThreads;
|
||||
};
|
||||
|
||||
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
|
||||
index d56379466..1da7ccbb2 100644
|
||||
--- a/ldap/servers/slapd/snmp_collator.c
|
||||
+++ b/ldap/servers/slapd/snmp_collator.c
|
||||
@@ -122,7 +122,7 @@ snmp_collator_init(void)
|
||||
g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned = slapi_counter_new();
|
||||
g_get_global_snmp_vars()->ops_tbl.dsReferralsReturned = slapi_counter_new();
|
||||
g_get_global_snmp_vars()->ops_tbl.dsConnectionsInMaxThreads = slapi_counter_new();
|
||||
- g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHit = slapi_counter_new();
|
||||
+ g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHits = slapi_counter_new();
|
||||
g_get_global_snmp_vars()->entries_tbl.dsMasterEntries = slapi_counter_new();
|
||||
g_get_global_snmp_vars()->entries_tbl.dsCopyEntries = slapi_counter_new();
|
||||
g_get_global_snmp_vars()->entries_tbl.dsCacheEntries = slapi_counter_new();
|
||||
@@ -592,7 +592,7 @@ snmp_update_ops_table(void)
|
||||
stats->ops_stats.dsConnections = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnections);
|
||||
stats->ops_stats.dsConnectionSeq = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq);
|
||||
stats->ops_stats.dsConnectionsInMaxThreads = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionsInMaxThreads);
|
||||
- stats->ops_stats.dsMaxThreadsHit = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHit);
|
||||
+ stats->ops_stats.dsMaxThreadsHits = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHits);
|
||||
stats->ops_stats.dsBytesRecv = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesRecv);
|
||||
stats->ops_stats.dsBytesSent = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesSent);
|
||||
stats->ops_stats.dsEntriesReturned = slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned);
|
||||
@@ -738,7 +738,7 @@ snmp_as_entry(Slapi_Entry *e)
|
||||
add_counter_to_value(e, "Connections", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnections));
|
||||
add_counter_to_value(e, "ConnectionSeq", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionSeq));
|
||||
add_counter_to_value(e, "ConnectionsInMaxThreads", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsConnectionsInMaxThreads));
|
||||
- add_counter_to_value(e, "ConnectionsMaxThreadsCount", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHit));
|
||||
+ add_counter_to_value(e, "ConnectionsMaxThreadsCount", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsMaxThreadsHits));
|
||||
add_counter_to_value(e, "BytesRecv", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesRecv));
|
||||
add_counter_to_value(e, "BytesSent", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsBytesSent));
|
||||
add_counter_to_value(e, "EntriesReturned", slapi_counter_get_value(g_get_global_snmp_vars()->ops_tbl.dsEntriesReturned));
|
||||
diff --git a/ldap/servers/snmp/ldap-agent.c b/ldap/servers/snmp/ldap-agent.c
|
||||
index 4393a8956..bd9b8dd9b 100644
|
||||
--- a/ldap/servers/snmp/ldap-agent.c
|
||||
+++ b/ldap/servers/snmp/ldap-agent.c
|
||||
@@ -496,8 +496,8 @@ dsOpsTable_get_value(netsnmp_request_info *request,
|
||||
the_stat = &context->ops_tbl.dsConnectionsInMaxThreads;
|
||||
break;
|
||||
|
||||
- case COLUMN_DSMAXTHREADSHIT:
|
||||
- the_stat = &context->ops_tbl.dsMaxThreadsHit;
|
||||
+ case COLUMN_DSMAXTHREADSHITS:
|
||||
+ the_stat = &context->ops_tbl.dsMaxThreadsHits;
|
||||
break;
|
||||
|
||||
default: /* We shouldn't get here */
|
||||
diff --git a/ldap/servers/snmp/ldap-agent.h b/ldap/servers/snmp/ldap-agent.h
|
||||
index 935d3a611..c98e467dd 100644
|
||||
--- a/ldap/servers/snmp/ldap-agent.h
|
||||
+++ b/ldap/servers/snmp/ldap-agent.h
|
||||
@@ -161,7 +161,7 @@ extern size_t snmptrap_oid_len;
|
||||
#define COLUMN_DSERRORS 20
|
||||
#define COLUMN_DSCONNECTIONS 21
|
||||
#define COLUMN_DSCONNECTIONSINMAXTHREADS 22
|
||||
-#define COLUMN_DSMAXTHREADSHIT 23
|
||||
+#define COLUMN_DSMAXTHREADSHITS 23
|
||||
#define dsOpsTable_COL_MIN 1
|
||||
#define dsOpsTable_COL_MAX 23
|
||||
|
||||
diff --git a/ldap/servers/snmp/redhat-directory.mib b/ldap/servers/snmp/redhat-directory.mib
|
||||
index c8608972e..579be8ee4 100644
|
||||
--- a/ldap/servers/snmp/redhat-directory.mib
|
||||
+++ b/ldap/servers/snmp/redhat-directory.mib
|
||||
@@ -87,7 +87,7 @@ RHDS-MIB DEFINITIONS ::= BEGIN
|
||||
dsErrors,
|
||||
dsConnections,
|
||||
dsConnectionsInMaxThreads,
|
||||
- dsMaxThreadsHit,
|
||||
+ dsMaxThreadsHits,
|
||||
dsMasterEntries,
|
||||
dsCopyEntries,
|
||||
dsCacheEntries,
|
||||
@@ -190,7 +190,7 @@ RHDS-MIB DEFINITIONS ::= BEGIN
|
||||
Counter64,
|
||||
dsConnectionsInMaxThreads
|
||||
Counter64,
|
||||
- dsMaxThreadsHit
|
||||
+ dsMaxThreadsHits
|
||||
Counter64
|
||||
|
||||
}
|
||||
@@ -472,7 +472,7 @@ RHDS-MIB DEFINITIONS ::= BEGIN
|
||||
"Redhat defined 1.2."
|
||||
::= { dsOpsEntry 22 }
|
||||
|
||||
- dsMaxThreadsHit OBJECT-TYPE
|
||||
+ dsMaxThreadsHits OBJECT-TYPE
|
||||
SYNTAX Counter64
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
@@ -596,7 +596,7 @@ RHDS-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
DsIntEntry ::= SEQUENCE {
|
||||
dsIntIndex
|
||||
- INTEGER,
|
||||
+ Integer32,
|
||||
dsName
|
||||
DistinguishedName,
|
||||
dsTimeOfCreation
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From 62fbb3423b26426e735e134134ab710945514ca6 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Tue, 26 Sep 2017 15:51:41 +0200
|
||||
Subject: [PATCH] Ticket: 49180 - errors log filled with attrlist_replace -
|
||||
attr_replace
|
||||
|
||||
Bug: If a RUV contains the same URL with different replica IDs the created referrals contain duplicates
|
||||
|
||||
Fix: check duplicate referrals
|
||||
|
||||
Reviewed by: Mark, thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_ruv.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
index 40dc0928b..7bfdc3425 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
@@ -1386,7 +1386,17 @@ ruv_replica_count(const RUV *ruv)
|
||||
* Extract all the referral URL's from the RUV (but self URL),
|
||||
* returning them in an array of strings, that
|
||||
* the caller must free.
|
||||
+ * We also check and remove duplicates (caused by unclean RUVs)
|
||||
*/
|
||||
+static int
|
||||
+ruv_referral_exists(unsigned char *purl, char **refs, int count)
|
||||
+{
|
||||
+ for (size_t j=0; j<count; j++) {
|
||||
+ if (0 == slapi_utf8casecmp(purl, (unsigned char *)refs[j]))
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
char **
|
||||
ruv_get_referrals(const RUV *ruv)
|
||||
{
|
||||
@@ -1407,7 +1417,8 @@ ruv_get_referrals(const RUV *ruv)
|
||||
/* Add URL into referrals if doesn't match self URL */
|
||||
if ((replica->replica_purl != NULL) &&
|
||||
(slapi_utf8casecmp((unsigned char *)replica->replica_purl,
|
||||
- (unsigned char *)mypurl) != 0)) {
|
||||
+ (unsigned char *)mypurl) != 0) &&
|
||||
+ !ruv_referral_exists((unsigned char *)replica->replica_purl, r, i)) {
|
||||
r[i] = slapi_ch_strdup(replica->replica_purl);
|
||||
i++;
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
From 6361810037bc32c22e3e00a16bc53b34d0b0d610 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 9 Jul 2018 15:50:09 -0400
|
||||
Subject: [PATCH] Ticket 49840 - ds-replcheck command returns traceback errors
|
||||
against ldif files having garbage content when run in offline mode
|
||||
|
||||
Description: Added a basic check to see if the LDIF files are actually
|
||||
LDIF files. Also added checks that the database RUV are
|
||||
present as well.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49840
|
||||
|
||||
Reviewed by: spichugi(Thanks!)
|
||||
|
||||
(cherry picked from commit 60cb52040704686d9541a2e2eb2765d86cb10af2)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-replcheck | 53 +++++++++++++++++++++++------
|
||||
1 file changed, 43 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||||
index 62f911034..5c195f983 100755
|
||||
--- a/ldap/admin/src/scripts/ds-replcheck
|
||||
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||||
@@ -10,18 +10,19 @@
|
||||
#
|
||||
|
||||
import os
|
||||
+import sys
|
||||
import re
|
||||
import time
|
||||
import ldap
|
||||
import ldapurl
|
||||
import argparse
|
||||
import getpass
|
||||
-
|
||||
+from ldif import LDIFRecordList
|
||||
from ldap.ldapobject import SimpleLDAPObject
|
||||
from ldap.cidict import cidict
|
||||
from ldap.controls import SimplePagedResultsControl
|
||||
|
||||
-VERSION = "1.3"
|
||||
+VERSION = "1.4"
|
||||
RUV_FILTER = '(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))'
|
||||
LDAP = 'ldap'
|
||||
LDAPS = 'ldaps'
|
||||
@@ -386,14 +387,17 @@ def ldif_search(LDIF, dn):
|
||||
return result
|
||||
|
||||
|
||||
-def get_dns(LDIF, opts):
|
||||
+def get_dns(LDIF, filename, opts):
|
||||
''' Get all the DN's from an LDIF file
|
||||
'''
|
||||
dns = []
|
||||
found = False
|
||||
+ found_ruv = False
|
||||
+ LDIF.seek(0)
|
||||
for line in LDIF:
|
||||
if line.startswith('dn: ') and line[4:].startswith('nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff'):
|
||||
opts['ruv_dn'] = line[4:].lower().strip()
|
||||
+ found_ruv = True
|
||||
elif line.startswith('dn: '):
|
||||
found = True
|
||||
dn = line[4:].lower().strip()
|
||||
@@ -407,6 +411,14 @@ def get_dns(LDIF, opts):
|
||||
found = False
|
||||
dns.append(dn)
|
||||
|
||||
+ if not found_ruv:
|
||||
+ print('Failed to find the database RUV in the LDIF file: ' + filename + ', the LDIF ' +
|
||||
+ 'file must contain replication state information.')
|
||||
+ dns = None
|
||||
+ else:
|
||||
+ # All good, reset cursor
|
||||
+ LDIF.seek(0)
|
||||
+
|
||||
return dns
|
||||
|
||||
|
||||
@@ -415,6 +427,7 @@ def get_ldif_ruv(LDIF, opts):
|
||||
'''
|
||||
LDIF.seek(0)
|
||||
result = ldif_search(LDIF, opts['ruv_dn'])
|
||||
+ LDIF.seek(0) # Reset cursor
|
||||
return result['entry'].data['nsds50ruv']
|
||||
|
||||
|
||||
@@ -549,6 +562,7 @@ def do_offline_report(opts, output_file=None):
|
||||
rconflicts = []
|
||||
rtombstones = 0
|
||||
mtombstones = 0
|
||||
+ idx = 0
|
||||
|
||||
# Open LDIF files
|
||||
try:
|
||||
@@ -561,12 +575,36 @@ def do_offline_report(opts, output_file=None):
|
||||
RLDIF = open(opts['rldif'], "r")
|
||||
except Exception as e:
|
||||
print('Failed to open Replica LDIF: ' + str(e))
|
||||
+ MLDIF.close()
|
||||
+ return None
|
||||
+
|
||||
+ # Verify LDIF Files
|
||||
+ try:
|
||||
+ print("Validating Master ldif file ({})...".format(opts['mldif']))
|
||||
+ LDIFRecordList(MLDIF).parse()
|
||||
+ except ValueError:
|
||||
+ print('Master LDIF file in invalid, aborting...')
|
||||
+ MLDIF.close()
|
||||
+ RLDIF.close()
|
||||
+ return None
|
||||
+ try:
|
||||
+ print("Validating Replica ldif file ({})...".format(opts['rldif']))
|
||||
+ LDIFRecordList(RLDIF).parse()
|
||||
+ except ValueError:
|
||||
+ print('Replica LDIF file is invalid, aborting...')
|
||||
+ MLDIF.close()
|
||||
+ RLDIF.close()
|
||||
return None
|
||||
|
||||
# Get all the dn's, and entry counts
|
||||
print ("Gathering all the DN's...")
|
||||
- master_dns = get_dns(MLDIF, opts)
|
||||
- replica_dns = get_dns(RLDIF, opts)
|
||||
+ master_dns = get_dns(MLDIF, opts['mldif'], opts)
|
||||
+ replica_dns = get_dns(RLDIF, opts['rldif'], opts)
|
||||
+ if master_dns is None or replica_dns is None:
|
||||
+ print("Aborting scan...")
|
||||
+ MLDIF.close()
|
||||
+ RLDIF.close()
|
||||
+ sys.exit(1)
|
||||
m_count = len(master_dns)
|
||||
r_count = len(replica_dns)
|
||||
|
||||
@@ -575,11 +613,6 @@ def do_offline_report(opts, output_file=None):
|
||||
opts['master_ruv'] = get_ldif_ruv(MLDIF, opts)
|
||||
opts['replica_ruv'] = get_ldif_ruv(RLDIF, opts)
|
||||
|
||||
- # Reset the cursors
|
||||
- idx = 0
|
||||
- MLDIF.seek(idx)
|
||||
- RLDIF.seek(idx)
|
||||
-
|
||||
""" Compare the master entries with the replica's. Take our list of dn's from
|
||||
the master ldif and get that entry( dn) from the master and replica ldif. In
|
||||
this phase we keep keep track of conflict/tombstone counts, and we check for
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
From 80631ee86fa951f18ed25f61ca72734931eb5387 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 2 Oct 2017 16:19:47 -0400
|
||||
Subject: [PATCH] Ticket 49388 - repl-monitor - matches null string many times
|
||||
in regex
|
||||
|
||||
Bug Description: When using a wildcard(*) for the hostname, some of the
|
||||
regex's for parsing the various configurations throws
|
||||
out warnings.
|
||||
|
||||
Fix Description: When a wildcard is detected reset the hostnode variable
|
||||
to nothing.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49388
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 4b41a02484db645a593b9d6ac6c4e062dd374395)
|
||||
---
|
||||
ldap/admin/src/scripts/repl-monitor.pl.in | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/repl-monitor.pl.in b/ldap/admin/src/scripts/repl-monitor.pl.in
|
||||
index a3efa8e6e..97c1462a5 100755
|
||||
--- a/ldap/admin/src/scripts/repl-monitor.pl.in
|
||||
+++ b/ldap/admin/src/scripts/repl-monitor.pl.in
|
||||
@@ -1053,6 +1053,10 @@ sub add_server
|
||||
# Remove the domain name from the host name
|
||||
my ($hostnode) = $host;
|
||||
$hostnode = $1 if $host =~ /^(.+?)\./;
|
||||
+ if ($hostnode eq "*") {
|
||||
+ # handle wild card correctly for regex
|
||||
+ $hostnode = "";
|
||||
+ }
|
||||
|
||||
# new host:port
|
||||
if (!$binddn || $binddn eq "" || $binddn eq "*" ||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From 911038990df1357f452b0e38309261faf1de898f Mon Sep 17 00:00:00 2001
|
||||
From 83949e7e4f3370f48ea5c5fabdb9af04e3d11c75 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 8 Aug 2018 17:19:27 -0400
|
||||
Subject: [PATCH] Ticket 49893 - disable nunc-stans by default
|
||||
|
@ -15,10 +15,10 @@ Reviewed by: ?
|
|||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index 3bd5c1826..f8741028d 100644
|
||||
index 12f6ec396..56b67b79b 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -1681,7 +1681,7 @@ FrontendConfig_init(void)
|
||||
@@ -1683,7 +1683,7 @@ FrontendConfig_init(void)
|
||||
cfg->maxbersize = SLAPD_DEFAULT_MAXBERSIZE;
|
||||
cfg->logging_backend = slapi_ch_strdup(SLAPD_INIT_LOGGING_BACKEND_INTERNAL);
|
||||
cfg->rootdn = slapi_ch_strdup(SLAPD_DEFAULT_DIRECTORY_MANAGER);
|
|
@ -1,257 +0,0 @@
|
|||
From bb2d74ebe9d725b47e35893a2d8c8bd713d6dd4b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 3 Oct 2017 17:22:37 -0400
|
||||
Subject: [PATCH] Ticket 49389 - unable to retrieve specific cosAttribute when
|
||||
subtree password policy is configured
|
||||
|
||||
Bug Description: If indirect cos is being used and a subtree password
|
||||
policy is added, th orignal COS attributes aren't always
|
||||
returned. The issue is that when the subtree password
|
||||
policy attribute was encountered during the virtual
|
||||
attribute processing it set a flag that said the attribute
|
||||
was operational (which is correct for the password policy
|
||||
attr: pwdpolicysubentry).
|
||||
|
||||
However, this flag was accidentally carried over to the
|
||||
following virtual attributes that were being processed.
|
||||
Which caused those attributes to be seen as operational
|
||||
which is why it was no longer being returned to the client.
|
||||
|
||||
Fix Description: Reset the prop flags before processing the next COS attribute
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49389
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 0953e6011368bc29300990e9493ac13e5aba9586)
|
||||
---
|
||||
dirsrvtests/tests/suites/cos/__init__.py | 0
|
||||
dirsrvtests/tests/suites/cos/indirect_cos_test.py | 191 ++++++++++++++++++++++
|
||||
ldap/servers/plugins/cos/cos_cache.c | 2 +-
|
||||
3 files changed, 192 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/cos/__init__.py
|
||||
create mode 100644 dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/cos/__init__.py b/dirsrvtests/tests/suites/cos/__init__.py
|
||||
new file mode 100644
|
||||
index 000000000..e69de29bb
|
||||
diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
new file mode 100644
|
||||
index 000000000..1aac6b8ed
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
@@ -0,0 +1,191 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import ldap
|
||||
+import time
|
||||
+import subprocess
|
||||
+
|
||||
+from lib389 import Entry
|
||||
+from lib389.idm.user import UserAccounts
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE,
|
||||
+ SERVERID_STANDALONE, PORT_STANDALONE)
|
||||
+
|
||||
+
|
||||
+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__)
|
||||
+
|
||||
+TEST_USER_DN = "uid=test_user,ou=people,dc=example,dc=com"
|
||||
+OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX)
|
||||
+
|
||||
+PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,' \
|
||||
+ 'ou=people,dc=example,dc=com",' \
|
||||
+ 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
|
||||
+
|
||||
+PW_POLICY_CONT_PEOPLE2 = 'cn="cn=nsPwPolicyEntry,' \
|
||||
+ 'dc=example,dc=com",' \
|
||||
+ 'cn=nsPwPolicyContainerdc=example,dc=com'
|
||||
+
|
||||
+
|
||||
+def check_user(inst):
|
||||
+ """Search the test user and make sure it has the execpted attrs
|
||||
+ """
|
||||
+ try:
|
||||
+ entries = inst.search_s('dc=example,dc=com', ldap.SCOPE_SUBTREE, "uid=test_user")
|
||||
+ log.debug('user: \n' + str(entries[0]))
|
||||
+ assert entries[0].hasAttr('ou'), "Entry is missing ou cos attribute"
|
||||
+ assert entries[0].hasAttr('x-department'), "Entry is missing description cos attribute"
|
||||
+ assert entries[0].hasAttr('x-en-ou'), "Entry is missing givenname cos attribute"
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to search for user: ' + str(e))
|
||||
+ raise e
|
||||
+
|
||||
+
|
||||
+def setup_subtree_policy(topo):
|
||||
+ """Set up subtree password policy
|
||||
+ """
|
||||
+ try:
|
||||
+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE,
|
||||
+ 'nsslapd-pwpolicy-local',
|
||||
+ 'on')])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to set fine-grained policy: error {}'.format(
|
||||
+ e.message['desc']))
|
||||
+ raise e
|
||||
+
|
||||
+ log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
|
||||
+ try:
|
||||
+ subprocess.call(['%s/ns-newpwpolicy.pl' % topo.standalone.get_sbin_dir(),
|
||||
+ '-D', DN_DM, '-w', PASSWORD,
|
||||
+ '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
|
||||
+ '-S', DEFAULT_SUFFIX, '-Z', SERVERID_STANDALONE])
|
||||
+ except subprocess.CalledProcessError as e:
|
||||
+ log.error('Failed to create pw policy policy for {}: error {}'.format(
|
||||
+ OU_PEOPLE, e.message['desc']))
|
||||
+ raise e
|
||||
+
|
||||
+ log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE,
|
||||
+ 'pwdpolicysubentry',
|
||||
+ PW_POLICY_CONT_PEOPLE2)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to pwdpolicysubentry pw policy '
|
||||
+ 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc']))
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+
|
||||
+def setup_indirect_cos(topo):
|
||||
+ """Setup indirect COS definition and template
|
||||
+ """
|
||||
+ cosDef = Entry(('cn=cosDefinition,dc=example,dc=com',
|
||||
+ {'objectclass': ['top', 'ldapsubentry',
|
||||
+ 'cossuperdefinition',
|
||||
+ 'cosIndirectDefinition'],
|
||||
+ 'cosAttribute': ['ou merge-schemes',
|
||||
+ 'x-department merge-schemes',
|
||||
+ 'x-en-ou merge-schemes'],
|
||||
+ 'cosIndirectSpecifier': 'seeAlso',
|
||||
+ 'cn': 'cosDefinition'}))
|
||||
+
|
||||
+ cosTemplate = Entry(('cn=cosTemplate,dc=example,dc=com',
|
||||
+ {'objectclass': ['top',
|
||||
+ 'extensibleObject',
|
||||
+ 'cosTemplate'],
|
||||
+ 'ou': 'My COS Org',
|
||||
+ 'x-department': 'My COS x-department',
|
||||
+ 'x-en-ou': 'my COS x-en-ou',
|
||||
+ 'cn': 'cosTemplate'}))
|
||||
+ try:
|
||||
+ topo.standalone.add_s(cosDef)
|
||||
+ topo.standalone.add_s(cosTemplate)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add cos: error ' + str(e))
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+
|
||||
+@pytest.fixture(scope="module")
|
||||
+def setup(topo, request):
|
||||
+ """Add schema, and test user
|
||||
+ """
|
||||
+ log.info('Add custom schema...')
|
||||
+ try:
|
||||
+ ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " +
|
||||
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " +
|
||||
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " +
|
||||
+ "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )")
|
||||
+ topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1),
|
||||
+ (ldap.MOD_ADD, 'attributeTypes', ATTR_2),
|
||||
+ (ldap.MOD_ADD, 'objectClasses', OC)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add custom schema')
|
||||
+ raise e
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ log.info('Add test user...')
|
||||
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
|
||||
+
|
||||
+ user_properties = {
|
||||
+ 'uid': 'test_user',
|
||||
+ 'cn': 'test user',
|
||||
+ 'sn': 'user',
|
||||
+ 'uidNumber': '1000',
|
||||
+ 'gidNumber': '2000',
|
||||
+ 'homeDirectory': '/home/test_user',
|
||||
+ 'seeAlso': 'cn=cosTemplate,dc=example,dc=com'
|
||||
+ }
|
||||
+ users.create(properties=user_properties)
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD,
|
||||
+ 'objectclass',
|
||||
+ 'xPerson')])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add objectclass to user')
|
||||
+ raise e
|
||||
+
|
||||
+ # Setup COS
|
||||
+ log.info("Setup indirect COS...")
|
||||
+ setup_indirect_cos(topo)
|
||||
+
|
||||
+
|
||||
+def test_indirect_cos(topo, setup):
|
||||
+ """Test indirect cos
|
||||
+
|
||||
+ :id: 890d5929-7d52-4a56-956e-129611b4649a
|
||||
+ :setup: standalone
|
||||
+ :steps:
|
||||
+ 1. Test cos is working for test user
|
||||
+ 2. Add subtree password policy
|
||||
+ 3. Test cos is working for test user
|
||||
+ :expectedresults:
|
||||
+ 1. User has expected cos attrs
|
||||
+ 2. Substree password policy setup is successful
|
||||
+ 3 User still has expected cos attrs
|
||||
+ """
|
||||
+
|
||||
+ # Step 1 - Search user and see if the COS attrs are included
|
||||
+ log.info('Checking user...')
|
||||
+ check_user(topo.standalone)
|
||||
+
|
||||
+ # Step 2 - Add subtree password policy (Second COS - operational attribute)
|
||||
+ setup_subtree_policy(topo)
|
||||
+
|
||||
+ # Step 3 - Check user again now hat we have a mix of vattrs
|
||||
+ log.info('Checking user...')
|
||||
+ check_user(topo.standalone)
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index c7897ba05..9ae15db15 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -2094,7 +2094,6 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
|
||||
int index = 0;
|
||||
cosCache *pCache;
|
||||
char *lastattr = "thisisfakeforcos";
|
||||
- int props = 0;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
|
||||
|
||||
@@ -2105,6 +2104,7 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
|
||||
}
|
||||
|
||||
while (index < pCache->attrCount) {
|
||||
+ int props = 0;
|
||||
if (slapi_utf8casecmp(
|
||||
(unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
||||
(unsigned char *)lastattr)) {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From 1013a1bfe0882d213f48e900ab89e00651188489 Mon Sep 17 00:00:00 2001
|
||||
From a21ba4722268349b9c63000145e5d119e1fddd60 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 9 Aug 2018 15:27:59 -0400
|
||||
Subject: [PATCH] Ticket 49890 : ldapsearch with server side sort crashes the
|
|
@ -1,17 +1,17 @@
|
|||
From 9d2aa18fb5c48a11300d2309df89213bbdb614e1 Mon Sep 17 00:00:00 2001
|
||||
From 59071a77774c530f0ab570dda27e23a021d23972 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 23 Aug 2018 13:43:36 -0400
|
||||
Subject: [PATCH 1/2] Bug 1623247 - Crash in vslapd_log_emergency_error
|
||||
Date: Thu, 23 Aug 2018 10:09:58 -0400
|
||||
Subject: [PATCH] Bug 1614820 - Crash in vslapd_log_emergency_error
|
||||
|
||||
Description: We were not locking the error log fd before closing and reopening
|
||||
the log file. This could cause a crash when multiple threads are
|
||||
trying to log tothe errors log.
|
||||
Description: We were not locking the error log fd before closing and reopening
|
||||
the log file. This could cause a crash when multiple threads are
|
||||
trying to log tothe errors log.
|
||||
---
|
||||
ldap/servers/slapd/log.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
|
||||
index 998efaef3..90ce6ac0a 100644
|
||||
index 2e4ee03a8..7dd71541b 100644
|
||||
--- a/ldap/servers/slapd/log.c
|
||||
+++ b/ldap/servers/slapd/log.c
|
||||
@@ -2231,11 +2231,11 @@ vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked)
|
||||
|
@ -54,7 +54,7 @@ index 998efaef3..90ce6ac0a 100644
|
|||
log__error_emergency("Insufficent buffer capacity to fit timestamp and message!", 1, 0);
|
||||
return -1;
|
||||
}
|
||||
@@ -4447,6 +4447,13 @@ log__error_emergency(const char *errstr, int reopen, int locked)
|
||||
@@ -4486,6 +4486,13 @@ log__error_emergency(const char *errstr, int reopen, int locked)
|
||||
if (!reopen) {
|
||||
return;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ index 998efaef3..90ce6ac0a 100644
|
|||
if (NULL != loginfo.log_error_fdes) {
|
||||
LOG_CLOSE(loginfo.log_error_fdes);
|
||||
}
|
||||
@@ -4455,7 +4462,10 @@ log__error_emergency(const char *errstr, int reopen, int locked)
|
||||
@@ -4494,7 +4501,10 @@ log__error_emergency(const char *errstr, int reopen, int locked)
|
||||
PRErrorCode prerr = PR_GetError();
|
||||
syslog(LOG_ERR, "Failed to reopen errors log file, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr));
|
||||
} else {
|
|
@ -1,111 +0,0 @@
|
|||
From 50d62b6d5ea69e5cad6359dbd1dccb09fcfa1a6b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 3 Oct 2017 09:51:53 -0400
|
||||
Subject: [PATCH] Ticket 49320 - Activating already active role returns error
|
||||
16
|
||||
|
||||
Bug Description: ns-activate.pl returns error 16 when trying to activate an
|
||||
already active role.
|
||||
|
||||
Fix Description: Check for error 16 (no such attr), and return error 100.
|
||||
Also added a "redirect"otion to the ldapmod function to
|
||||
hide any errors printed to STDERR, so that the script can
|
||||
display its own error message.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49320
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 406084847f29aa44ffd81de746770aeff6b67c61)
|
||||
---
|
||||
ldap/admin/src/scripts/DSUtil.pm.in | 18 +++++++++++-------
|
||||
ldap/admin/src/scripts/ns-activate.pl.in | 9 ++++++++-
|
||||
2 files changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/DSUtil.pm.in b/ldap/admin/src/scripts/DSUtil.pm.in
|
||||
index 805a9b91d..791464d0a 100644
|
||||
--- a/ldap/admin/src/scripts/DSUtil.pm.in
|
||||
+++ b/ldap/admin/src/scripts/DSUtil.pm.in
|
||||
@@ -1447,6 +1447,10 @@ sub ldapmod {
|
||||
close (FILE);
|
||||
}
|
||||
|
||||
+ if ($info{redirect} eq ""){
|
||||
+ $info{redirect} = "> /dev/null";
|
||||
+ }
|
||||
+
|
||||
#
|
||||
# Check the protocol, and reset it if it's invalid
|
||||
#
|
||||
@@ -1470,9 +1474,9 @@ sub ldapmod {
|
||||
print "STARTTLS)\n";
|
||||
}
|
||||
if($info{openldap} eq "yes"){
|
||||
- system "ldapmodify -x -ZZ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -x -ZZ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
} else {
|
||||
- system "ldapmodify -ZZZ -P \"$info{certdir}\" -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -ZZZ -P \"$info{certdir}\" -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
}
|
||||
} elsif (($info{security} eq "on" && $info{protocol} eq "") || ($info{security} eq "on" && $info{protocol} =~ m/LDAPS/i) ){
|
||||
#
|
||||
@@ -1482,9 +1486,9 @@ sub ldapmod {
|
||||
print "LDAPS)\n";
|
||||
}
|
||||
if($info{openldap} eq "yes"){
|
||||
- system "ldapmodify -x -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -x -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
} else {
|
||||
- system "ldapmodify -Z -P \"$info{certdir}\" -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -Z -P \"$info{certdir}\" -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
}
|
||||
} elsif (($info{openldap} eq "yes") && (($info{ldapi} eq "on" && $info{protocol} eq "") || ($info{ldapi} eq "on" && $info{protocol} =~ m/LDAPI/i)) ){
|
||||
#
|
||||
@@ -1499,7 +1503,7 @@ sub ldapmod {
|
||||
if($protocol_error eq "yes"){
|
||||
print "LDAPI)\n";
|
||||
}
|
||||
- system "ldapmodify -x -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -x -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
}
|
||||
} else {
|
||||
#
|
||||
@@ -1509,9 +1513,9 @@ sub ldapmod {
|
||||
print "LDAP)\n";
|
||||
}
|
||||
if($info{openldap} eq "yes"){
|
||||
- system "ldapmodify -x -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -x -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
} else {
|
||||
- system "ldapmodify -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null";
|
||||
+ system "ldapmodify -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}";
|
||||
}
|
||||
}
|
||||
unlink ($file);
|
||||
diff --git a/ldap/admin/src/scripts/ns-activate.pl.in b/ldap/admin/src/scripts/ns-activate.pl.in
|
||||
index 5922c9aab..bec19c8e7 100644
|
||||
--- a/ldap/admin/src/scripts/ns-activate.pl.in
|
||||
+++ b/ldap/admin/src/scripts/ns-activate.pl.in
|
||||
@@ -731,11 +731,18 @@ if ( $single == 1 ){
|
||||
}
|
||||
|
||||
$info{args} = "-c";
|
||||
+$info{redirect} = "> /dev/null 2>&1";
|
||||
DSUtil::ldapmod($record, %info);
|
||||
if( $? != 0 ){
|
||||
debug("delete, $entry\n");
|
||||
$retCode=$?>>8;
|
||||
- exit $retCode;
|
||||
+ if ($retCode == "16") { # Error 16 (no such attr) - already activated
|
||||
+ out("$entry already $state.\n");
|
||||
+ exit 100;
|
||||
+ } else {
|
||||
+ out("Failed to activate $entry, error $retCode\n");
|
||||
+ exit $retCode;
|
||||
+ }
|
||||
}
|
||||
|
||||
out("$entry $state.\n");
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,914 +0,0 @@
|
|||
From cbe71d7e4901232eaa423b9dc55dba9401c05bec Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 13 Oct 2017 07:09:08 -0400
|
||||
Subject: [PATCH] Ticket 48235 - Remove memberOf global lock
|
||||
|
||||
Bug Description: The memberOf global lock no longer servers a purpose since
|
||||
the plugin is BETXN. This was causing potential deadlocks
|
||||
when multiple backends are used.
|
||||
|
||||
Fix Description: Remove the lock, and rework the fixup/ancestors caches/hashtables.
|
||||
Instead of reusing a single cache, we create a fresh cache
|
||||
when we copy the plugin config (which only happens at the start
|
||||
of an operation). Then we destroy the caches when we free
|
||||
the config.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48235
|
||||
|
||||
Reviewed by: firstyear & tbordaz(Thanks!!)
|
||||
|
||||
(cherry picked from commit 184b8a164f4ed456c72d58038aa9a0d512be61fa)
|
||||
---
|
||||
ldap/servers/plugins/memberof/memberof.c | 326 +++---------------------
|
||||
ldap/servers/plugins/memberof/memberof.h | 17 ++
|
||||
ldap/servers/plugins/memberof/memberof_config.c | 166 +++++++++++-
|
||||
3 files changed, 210 insertions(+), 299 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index a0f997ddf..a23c52abe 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -48,14 +48,11 @@ static Slapi_PluginDesc pdesc = {"memberof", VENDOR,
|
||||
static void *_PluginID = NULL;
|
||||
static Slapi_DN *_ConfigAreaDN = NULL;
|
||||
static Slapi_RWLock *config_rwlock = NULL;
|
||||
-static Slapi_DN *_pluginDN = NULL;
|
||||
-static PRMonitor *memberof_operation_lock = 0;
|
||||
+static Slapi_DN* _pluginDN = NULL;
|
||||
MemberOfConfig *qsortConfig = 0;
|
||||
static int usetxn = 0;
|
||||
static int premodfn = 0;
|
||||
-#define MEMBEROF_HASHTABLE_SIZE 1000
|
||||
-static PLHashTable *fixup_entry_hashtable = NULL; /* global hash table protected by memberof_lock (memberof_operation_lock) */
|
||||
-static PLHashTable *group_ancestors_hashtable = NULL; /* global hash table protected by memberof_lock (memberof_operation_lock) */
|
||||
+
|
||||
|
||||
typedef struct _memberofstringll
|
||||
{
|
||||
@@ -73,18 +70,6 @@ typedef struct _memberof_get_groups_data
|
||||
PRBool use_cache;
|
||||
} memberof_get_groups_data;
|
||||
|
||||
-/* The key to access the hash table is the normalized DN
|
||||
- * The normalized DN is stored in the value because:
|
||||
- * - It is used in slapi_valueset_find
|
||||
- * - It is used to fill the memberof_get_groups_data.group_norm_vals
|
||||
- */
|
||||
-typedef struct _memberof_cached_value
|
||||
-{
|
||||
- char *key;
|
||||
- char *group_dn_val;
|
||||
- char *group_ndn_val;
|
||||
- int valid;
|
||||
-} memberof_cached_value;
|
||||
struct cache_stat
|
||||
{
|
||||
int total_lookup;
|
||||
@@ -164,14 +149,9 @@ static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
|
||||
static int memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn);
|
||||
static int memberof_add_objectclass(char *auto_add_oc, const char *dn);
|
||||
static int memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc);
|
||||
-static PLHashTable *hashtable_new();
|
||||
-static void fixup_hashtable_empty(char *msg);
|
||||
-static PLHashTable *hashtable_new();
|
||||
-static void ancestor_hashtable_empty(char *msg);
|
||||
-static void ancestor_hashtable_entry_free(memberof_cached_value *entry);
|
||||
-static memberof_cached_value *ancestors_cache_lookup(const char *ndn);
|
||||
-static PRBool ancestors_cache_remove(const char *ndn);
|
||||
-static PLHashEntry *ancestors_cache_add(const void *key, void *value);
|
||||
+static memberof_cached_value *ancestors_cache_lookup(MemberOfConfig *config, const char *ndn);
|
||||
+static PRBool ancestors_cache_remove(MemberOfConfig *config, const char *ndn);
|
||||
+static PLHashEntry *ancestors_cache_add(MemberOfConfig *config, const void *key, void *value);
|
||||
|
||||
/*** implementation ***/
|
||||
|
||||
@@ -344,11 +324,6 @@ memberof_postop_start(Slapi_PBlock *pb)
|
||||
slapi_log_err(SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
|
||||
"--> memberof_postop_start\n");
|
||||
|
||||
- memberof_operation_lock = PR_NewMonitor();
|
||||
- if (0 == memberof_operation_lock) {
|
||||
- rc = -1;
|
||||
- goto bail;
|
||||
- }
|
||||
if (config_rwlock == NULL) {
|
||||
if ((config_rwlock = slapi_new_rwlock()) == NULL) {
|
||||
rc = -1;
|
||||
@@ -356,9 +331,6 @@ memberof_postop_start(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
|
||||
- fixup_entry_hashtable = hashtable_new();
|
||||
- group_ancestors_hashtable = hashtable_new();
|
||||
-
|
||||
/* Set the alternate config area if one is defined. */
|
||||
slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area);
|
||||
if (config_area) {
|
||||
@@ -413,13 +385,13 @@ memberof_postop_start(Slapi_PBlock *pb)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
-/*
|
||||
+ /*
|
||||
* TODO: start up operation actor thread
|
||||
* need to get to a point where server failure
|
||||
- * or shutdown doesn't hose our operations
|
||||
- * so we should create a task entry that contains
|
||||
+ * or shutdown doesn't hose our operations
|
||||
+ * so we should create a task entry that contains
|
||||
* all required information to complete the operation
|
||||
- * then the tasks can be restarted safely if
|
||||
+ * then the tasks can be restarted safely if
|
||||
* interrupted
|
||||
*/
|
||||
|
||||
@@ -451,18 +423,7 @@ memberof_postop_close(Slapi_PBlock *pb __attribute__((unused)))
|
||||
slapi_sdn_free(&_pluginDN);
|
||||
slapi_destroy_rwlock(config_rwlock);
|
||||
config_rwlock = NULL;
|
||||
- PR_DestroyMonitor(memberof_operation_lock);
|
||||
- memberof_operation_lock = NULL;
|
||||
-
|
||||
- if (fixup_entry_hashtable) {
|
||||
- fixup_hashtable_empty("memberof_postop_close empty fixup_entry_hastable");
|
||||
- PL_HashTableDestroy(fixup_entry_hashtable);
|
||||
- }
|
||||
|
||||
- if (group_ancestors_hashtable) {
|
||||
- ancestor_hashtable_empty("memberof_postop_close empty group_ancestors_hashtable");
|
||||
- PL_HashTableDestroy(group_ancestors_hashtable);
|
||||
- }
|
||||
slapi_log_err(SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
|
||||
"<-- memberof_postop_close\n");
|
||||
return 0;
|
||||
@@ -524,7 +485,7 @@ memberof_postop_del(Slapi_PBlock *pb)
|
||||
{
|
||||
int ret = SLAPI_PLUGIN_SUCCESS;
|
||||
MemberOfConfig *mainConfig = NULL;
|
||||
- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ MemberOfConfig configCopy = {0};
|
||||
Slapi_DN *sdn;
|
||||
void *caller_id = NULL;
|
||||
|
||||
@@ -553,9 +514,6 @@ memberof_postop_del(Slapi_PBlock *pb)
|
||||
memberof_copy_config(&configCopy, memberof_get_config());
|
||||
memberof_unlock_config();
|
||||
|
||||
- /* get the memberOf operation lock */
|
||||
- memberof_lock();
|
||||
-
|
||||
/* remove this DN from the
|
||||
* membership lists of groups
|
||||
*/
|
||||
@@ -563,7 +521,6 @@ memberof_postop_del(Slapi_PBlock *pb)
|
||||
slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM,
|
||||
"memberof_postop_del - Error deleting dn (%s) from group. Error (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), ret);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
|
||||
@@ -583,7 +540,6 @@ memberof_postop_del(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
- memberof_unlock();
|
||||
bail:
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
@@ -776,7 +732,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb __attribute__((unused)), Slapi_DN *sdn
|
||||
memberof_cached_value *ht_grp = NULL;
|
||||
const char *ndn = slapi_sdn_get_ndn(sdn);
|
||||
|
||||
- ht_grp = ancestors_cache_lookup((const void *)ndn);
|
||||
+ ht_grp = ancestors_cache_lookup(config, (const void *)ndn);
|
||||
if (ht_grp) {
|
||||
#if MEMBEROF_CACHE_DEBUG
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_call_foreach_dn: Ancestors of %s already cached (%x)\n", ndn, ht_grp);
|
||||
@@ -918,7 +874,7 @@ memberof_postop_modrdn(Slapi_PBlock *pb)
|
||||
|
||||
if (memberof_oktodo(pb)) {
|
||||
MemberOfConfig *mainConfig = 0;
|
||||
- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ MemberOfConfig configCopy = {0};
|
||||
struct slapi_entry *pre_e = NULL;
|
||||
struct slapi_entry *post_e = NULL;
|
||||
Slapi_DN *pre_sdn = 0;
|
||||
@@ -944,8 +900,6 @@ memberof_postop_modrdn(Slapi_PBlock *pb)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
- memberof_lock();
|
||||
-
|
||||
/* update any downstream members */
|
||||
if (pre_sdn && post_sdn && configCopy.group_filter &&
|
||||
0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) {
|
||||
@@ -1010,7 +964,6 @@ memberof_postop_modrdn(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
- memberof_unlock();
|
||||
bail:
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
@@ -1166,7 +1119,7 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
if (memberof_oktodo(pb)) {
|
||||
int config_copied = 0;
|
||||
MemberOfConfig *mainConfig = 0;
|
||||
- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ MemberOfConfig configCopy = {0};
|
||||
|
||||
/* get the mod set */
|
||||
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
|
||||
@@ -1209,8 +1162,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
if (interested) {
|
||||
int op = slapi_mod_get_operation(smod);
|
||||
|
||||
- memberof_lock();
|
||||
-
|
||||
/* the modify op decides the function */
|
||||
switch (op & ~LDAP_MOD_BVALUES) {
|
||||
case LDAP_MOD_ADD: {
|
||||
@@ -1221,7 +1172,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"Error (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), ret);
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
@@ -1239,7 +1189,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"Error (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), ret);
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
} else {
|
||||
@@ -1250,7 +1199,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"Error (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), ret);
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@@ -1265,7 +1213,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"Error (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), ret);
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
@@ -1280,8 +1227,6 @@ memberof_postop_modify(Slapi_PBlock *pb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
-
|
||||
- memberof_unlock();
|
||||
}
|
||||
|
||||
slapi_mod_done(next_mod);
|
||||
@@ -1336,7 +1281,7 @@ memberof_postop_add(Slapi_PBlock *pb)
|
||||
|
||||
if (memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) {
|
||||
struct slapi_entry *e = NULL;
|
||||
- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ MemberOfConfig configCopy = {0};
|
||||
MemberOfConfig *mainConfig;
|
||||
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
|
||||
|
||||
@@ -1361,8 +1306,6 @@ memberof_postop_add(Slapi_PBlock *pb)
|
||||
int i = 0;
|
||||
Slapi_Attr *attr = 0;
|
||||
|
||||
- memberof_lock();
|
||||
-
|
||||
for (i = 0; configCopy.groupattrs && configCopy.groupattrs[i]; i++) {
|
||||
if (0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr)) {
|
||||
if ((ret = memberof_add_attr_list(pb, &configCopy, sdn, attr))) {
|
||||
@@ -1373,8 +1316,6 @@ memberof_postop_add(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- memberof_unlock();
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
}
|
||||
@@ -2094,7 +2035,7 @@ dump_cache_entry(memberof_cached_value *double_check, const char *msg)
|
||||
* the firsts elements of the array has 'valid=1' and the dn/ndn of group it belong to
|
||||
*/
|
||||
static void
|
||||
-cache_ancestors(Slapi_Value **member_ndn_val, memberof_get_groups_data *groups)
|
||||
+cache_ancestors(MemberOfConfig *config, Slapi_Value **member_ndn_val, memberof_get_groups_data *groups)
|
||||
{
|
||||
Slapi_ValueSet *groupvals = *((memberof_get_groups_data *)groups)->groupvals;
|
||||
Slapi_Value *sval;
|
||||
@@ -2191,14 +2132,14 @@ cache_ancestors(Slapi_Value **member_ndn_val, memberof_get_groups_data *groups)
|
||||
#if MEMBEROF_CACHE_DEBUG
|
||||
dump_cache_entry(cache_entry, key);
|
||||
#endif
|
||||
- if (ancestors_cache_add((const void *)key_copy, (void *)cache_entry) == NULL) {
|
||||
- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache_ancestors: Failed to cache ancestor of %s\n", key);
|
||||
+ if (ancestors_cache_add(config, (const void*) key_copy, (void *) cache_entry) == NULL) {
|
||||
+ slapi_log_err( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache_ancestors: Failed to cache ancestor of %s\n", key);
|
||||
ancestor_hashtable_entry_free(cache_entry);
|
||||
- slapi_ch_free((void **)&cache_entry);
|
||||
+ slapi_ch_free ((void**)&cache_entry);
|
||||
return;
|
||||
}
|
||||
#if MEMBEROF_CACHE_DEBUG
|
||||
- if (double_check = ancestors_cache_lookup((const void *)key)) {
|
||||
+ if (double_check = ancestors_cache_lookup(config, (const void*) key)) {
|
||||
dump_cache_entry(double_check, "read back");
|
||||
}
|
||||
#endif
|
||||
@@ -2283,8 +2224,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn, memberof_get
|
||||
|
||||
merge_ancestors(&member_ndn_val, &member_data, data);
|
||||
if (!cached && member_data.use_cache)
|
||||
- cache_ancestors(&member_ndn_val, &member_data);
|
||||
-
|
||||
+ cache_ancestors(config, &member_ndn_val, &member_data);
|
||||
|
||||
slapi_value_free(&member_ndn_val);
|
||||
slapi_valueset_free(groupvals);
|
||||
@@ -2825,49 +2765,10 @@ memberof_qsort_compare(const void *a, const void *b)
|
||||
val1, val2);
|
||||
}
|
||||
|
||||
-/* betxn: This locking mechanism is necessary to guarantee the memberof
|
||||
- * consistency */
|
||||
-void
|
||||
-memberof_lock()
|
||||
-{
|
||||
- if (usetxn) {
|
||||
- PR_EnterMonitor(memberof_operation_lock);
|
||||
- }
|
||||
- if (fixup_entry_hashtable) {
|
||||
- fixup_hashtable_empty("memberof_lock");
|
||||
- }
|
||||
- if (group_ancestors_hashtable) {
|
||||
- ancestor_hashtable_empty("memberof_lock empty group_ancestors_hashtable");
|
||||
- memset(&cache_stat, 0, sizeof(cache_stat));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-memberof_unlock()
|
||||
-{
|
||||
- if (group_ancestors_hashtable) {
|
||||
- ancestor_hashtable_empty("memberof_unlock empty group_ancestors_hashtable");
|
||||
-#if MEMBEROF_CACHE_DEBUG
|
||||
- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache statistics: total lookup %d (success %d), add %d, remove %d, enum %d\n",
|
||||
- cache_stat.total_lookup, cache_stat.successfull_lookup,
|
||||
- cache_stat.total_add, cache_stat.total_remove, cache_stat.total_enumerate);
|
||||
- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache statistics duration: lookup %ld, add %ld, remove %ld, enum %ld\n",
|
||||
- cache_stat.cumul_duration_lookup, cache_stat.cumul_duration_add,
|
||||
- cache_stat.cumul_duration_remove, cache_stat.cumul_duration_enumerate);
|
||||
-#endif
|
||||
- }
|
||||
- if (fixup_entry_hashtable) {
|
||||
- fixup_hashtable_empty("memberof_lock");
|
||||
- }
|
||||
- if (usetxn) {
|
||||
- PR_ExitMonitor(memberof_operation_lock);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void
|
||||
memberof_fixup_task_thread(void *arg)
|
||||
{
|
||||
- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ MemberOfConfig configCopy = {0};
|
||||
Slapi_Task *task = (Slapi_Task *)arg;
|
||||
task_data *td = NULL;
|
||||
int rc = 0;
|
||||
@@ -2933,9 +2834,6 @@ memberof_fixup_task_thread(void *arg)
|
||||
/* do real work */
|
||||
rc = memberof_fix_memberof(&configCopy, task, td);
|
||||
|
||||
- /* release the memberOf operation lock */
|
||||
- memberof_unlock();
|
||||
-
|
||||
done:
|
||||
if (usetxn && fixup_pb) {
|
||||
if (rc) { /* failed */
|
||||
@@ -3100,7 +2998,7 @@ memberof_fix_memberof(MemberOfConfig *config, Slapi_Task *task, task_data *td)
|
||||
}
|
||||
|
||||
static memberof_cached_value *
|
||||
-ancestors_cache_lookup(const char *ndn)
|
||||
+ancestors_cache_lookup(MemberOfConfig *config, const char *ndn)
|
||||
{
|
||||
memberof_cached_value *e;
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
@@ -3118,7 +3016,7 @@ ancestors_cache_lookup(const char *ndn)
|
||||
}
|
||||
#endif
|
||||
|
||||
- e = (memberof_cached_value *)PL_HashTableLookupConst(group_ancestors_hashtable, (const void *)ndn);
|
||||
+ e = (memberof_cached_value *) PL_HashTableLookupConst(config->ancestors_cache, (const void *) ndn);
|
||||
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
if (start) {
|
||||
@@ -3133,7 +3031,7 @@ ancestors_cache_lookup(const char *ndn)
|
||||
return e;
|
||||
}
|
||||
static PRBool
|
||||
-ancestors_cache_remove(const char *ndn)
|
||||
+ancestors_cache_remove(MemberOfConfig *config, const char *ndn)
|
||||
{
|
||||
PRBool rc;
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
@@ -3151,7 +3049,8 @@ ancestors_cache_remove(const char *ndn)
|
||||
}
|
||||
#endif
|
||||
|
||||
- rc = PL_HashTableRemove(group_ancestors_hashtable, (const void *)ndn);
|
||||
+
|
||||
+ rc = PL_HashTableRemove(config->ancestors_cache, (const void *)ndn);
|
||||
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
if (start) {
|
||||
@@ -3164,7 +3063,7 @@ ancestors_cache_remove(const char *ndn)
|
||||
}
|
||||
|
||||
static PLHashEntry *
|
||||
-ancestors_cache_add(const void *key, void *value)
|
||||
+ancestors_cache_add(MemberOfConfig *config, const void *key, void *value)
|
||||
{
|
||||
PLHashEntry *e;
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
@@ -3181,7 +3080,7 @@ ancestors_cache_add(const void *key, void *value)
|
||||
}
|
||||
#endif
|
||||
|
||||
- e = PL_HashTableAdd(group_ancestors_hashtable, key, value);
|
||||
+ e = PL_HashTableAdd(config->ancestors_cache, key, value);
|
||||
|
||||
#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
if (start) {
|
||||
@@ -3211,7 +3110,6 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
const char *ndn;
|
||||
char *dn_copy;
|
||||
|
||||
-
|
||||
/*
|
||||
* If the server is ordered to shutdown, stop the fixup and return an error.
|
||||
*/
|
||||
@@ -3222,7 +3120,7 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
|
||||
/* Check if the entry has not already been fixed */
|
||||
ndn = slapi_sdn_get_ndn(sdn);
|
||||
- if (ndn && fixup_entry_hashtable && PL_HashTableLookupConst(fixup_entry_hashtable, (void *)ndn)) {
|
||||
+ if (ndn && config->fixup_cache && PL_HashTableLookupConst(config->fixup_cache, (void *)ndn)) {
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: Entry %s already fixed up\n", ndn);
|
||||
goto bail;
|
||||
}
|
||||
@@ -3240,12 +3138,13 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
* so free this memory
|
||||
*/
|
||||
ndn = slapi_sdn_get_ndn(sdn);
|
||||
+
|
||||
#if MEMBEROF_CACHE_DEBUG
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: This is NOT a group %s\n", ndn);
|
||||
#endif
|
||||
- ht_grp = ancestors_cache_lookup((const void *)ndn);
|
||||
+ ht_grp = ancestors_cache_lookup(config, (const void *)ndn);
|
||||
if (ht_grp) {
|
||||
- if (ancestors_cache_remove((const void *)ndn)) {
|
||||
+ if (ancestors_cache_remove(config, (const void *)ndn)) {
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: free cached values for %s\n", ndn);
|
||||
ancestor_hashtable_entry_free(ht_grp);
|
||||
slapi_ch_free((void **)&ht_grp);
|
||||
@@ -3297,11 +3196,11 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
slapi_valueset_free(groups);
|
||||
|
||||
/* records that this entry has been fixed up */
|
||||
- if (fixup_entry_hashtable) {
|
||||
+ if (config->fixup_cache) {
|
||||
dn_copy = slapi_ch_strdup(ndn);
|
||||
- if (PL_HashTableAdd(fixup_entry_hashtable, dn_copy, dn_copy) == NULL) {
|
||||
+ if (PL_HashTableAdd(config->fixup_cache, dn_copy, dn_copy) == NULL) {
|
||||
slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: "
|
||||
- "failed to add dn (%s) in the fixup hashtable; NSPR error - %d\n",
|
||||
+ "failed to add dn (%s) in the fixup hashtable; NSPR error - %d\n",
|
||||
dn_copy, PR_GetError());
|
||||
slapi_ch_free((void **)&dn_copy);
|
||||
/* let consider this as not a fatal error, it just skip an optimization */
|
||||
@@ -3397,157 +3296,8 @@ memberof_add_objectclass(char *auto_add_oc, const char *dn)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static PRIntn
|
||||
-memberof_hash_compare_keys(const void *v1, const void *v2)
|
||||
-{
|
||||
- PRIntn rc;
|
||||
- if (0 == strcasecmp((const char *)v1, (const char *)v2)) {
|
||||
- rc = 1;
|
||||
- } else {
|
||||
- rc = 0;
|
||||
- }
|
||||
- return rc;
|
||||
-}
|
||||
-
|
||||
-static PRIntn
|
||||
-memberof_hash_compare_values(const void *v1, const void *v2)
|
||||
-{
|
||||
- PRIntn rc;
|
||||
- if ((char *)v1 == (char *)v2) {
|
||||
- rc = 1;
|
||||
- } else {
|
||||
- rc = 0;
|
||||
- }
|
||||
- return rc;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Hashing function using Bernstein's method
|
||||
- */
|
||||
-static PLHashNumber
|
||||
-memberof_hash_fn(const void *key)
|
||||
-{
|
||||
- PLHashNumber hash = 5381;
|
||||
- unsigned char *x = (unsigned char *)key;
|
||||
- int c;
|
||||
-
|
||||
- while ((c = *x++)) {
|
||||
- hash = ((hash << 5) + hash) ^ c;
|
||||
- }
|
||||
- return hash;
|
||||
-}
|
||||
-
|
||||
-/* allocates the plugin hashtable
|
||||
- * This hash table is used by operation and is protected from
|
||||
- * concurrent operations with the memberof_lock (if not usetxn, memberof_lock
|
||||
- * is not implemented and the hash table will be not used.
|
||||
- *
|
||||
- * The hash table contains all the DN of the entries for which the memberof
|
||||
- * attribute has been computed/updated during the current operation
|
||||
- *
|
||||
- * hash table should be empty at the beginning and end of the plugin callback
|
||||
- */
|
||||
-static PLHashTable *
|
||||
-hashtable_new()
|
||||
-{
|
||||
- if (!usetxn) {
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- return PL_NewHashTable(MEMBEROF_HASHTABLE_SIZE,
|
||||
- memberof_hash_fn,
|
||||
- memberof_hash_compare_keys,
|
||||
- memberof_hash_compare_values, NULL, NULL);
|
||||
-}
|
||||
-/* this function called for each hash node during hash destruction */
|
||||
-static PRIntn
|
||||
-fixup_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused)))
|
||||
-{
|
||||
- char *dn_copy;
|
||||
-
|
||||
- if (he == NULL) {
|
||||
- return HT_ENUMERATE_NEXT;
|
||||
- }
|
||||
- dn_copy = (char *)he->value;
|
||||
- slapi_ch_free_string(&dn_copy);
|
||||
-
|
||||
- return HT_ENUMERATE_REMOVE;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-fixup_hashtable_empty(char *msg)
|
||||
-{
|
||||
- if (fixup_entry_hashtable) {
|
||||
- PL_HashTableEnumerateEntries(fixup_entry_hashtable, fixup_hashtable_remove, msg);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-
|
||||
-/* allocates the plugin hashtable
|
||||
- * This hash table is used by operation and is protected from
|
||||
- * concurrent operations with the memberof_lock (if not usetxn, memberof_lock
|
||||
- * is not implemented and the hash table will be not used.
|
||||
- *
|
||||
- * The hash table contains all the DN of the entries for which the memberof
|
||||
- * attribute has been computed/updated during the current operation
|
||||
- *
|
||||
- * hash table should be empty at the beginning and end of the plugin callback
|
||||
- */
|
||||
-
|
||||
-static void
|
||||
-ancestor_hashtable_entry_free(memberof_cached_value *entry)
|
||||
-{
|
||||
- int i;
|
||||
- for (i = 0; entry[i].valid; i++) {
|
||||
- slapi_ch_free((void **)&entry[i].group_dn_val);
|
||||
- slapi_ch_free((void **)&entry[i].group_ndn_val);
|
||||
- }
|
||||
- /* Here we are at the ending element containing the key */
|
||||
- slapi_ch_free((void **)&entry[i].key);
|
||||
-}
|
||||
-/* this function called for each hash node during hash destruction */
|
||||
-static PRIntn
|
||||
-ancestor_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused)))
|
||||
-{
|
||||
- memberof_cached_value *group_ancestor_array;
|
||||
-
|
||||
- if (he == NULL) {
|
||||
- return HT_ENUMERATE_NEXT;
|
||||
- }
|
||||
-
|
||||
-
|
||||
- group_ancestor_array = (memberof_cached_value *)he->value;
|
||||
- ancestor_hashtable_entry_free(group_ancestor_array);
|
||||
- slapi_ch_free((void **)&group_ancestor_array);
|
||||
-
|
||||
- return HT_ENUMERATE_REMOVE;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-ancestor_hashtable_empty(char *msg)
|
||||
+int
|
||||
+memberof_use_txn()
|
||||
{
|
||||
-#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
- long int start;
|
||||
- struct timespec tsnow;
|
||||
-#endif
|
||||
-
|
||||
- if (group_ancestors_hashtable) {
|
||||
- cache_stat.total_enumerate++;
|
||||
-#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
- if (clock_gettime(CLOCK_REALTIME, &tsnow) != 0) {
|
||||
- start = 0;
|
||||
- } else {
|
||||
- start = tsnow.tv_nsec;
|
||||
- }
|
||||
-#endif
|
||||
- PL_HashTableEnumerateEntries(group_ancestors_hashtable, ancestor_hashtable_remove, msg);
|
||||
-
|
||||
-#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME)
|
||||
- if (start) {
|
||||
- if (clock_gettime(CLOCK_REALTIME, &tsnow) == 0) {
|
||||
- cache_stat.cumul_duration_enumerate += (tsnow.tv_nsec - start);
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
- }
|
||||
+ return usetxn;
|
||||
}
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
|
||||
index 4833ce221..ba64e9dfa 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.h
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.h
|
||||
@@ -64,8 +64,22 @@ typedef struct memberofconfig
|
||||
int skip_nested;
|
||||
int fixup_task;
|
||||
char *auto_add_oc;
|
||||
+ PLHashTable *ancestors_cache;
|
||||
+ PLHashTable *fixup_cache;
|
||||
} MemberOfConfig;
|
||||
|
||||
+/* The key to access the hash table is the normalized DN
|
||||
+ * The normalized DN is stored in the value because:
|
||||
+ * - It is used in slapi_valueset_find
|
||||
+ * - It is used to fill the memberof_get_groups_data.group_norm_vals
|
||||
+ */
|
||||
+typedef struct _memberof_cached_value
|
||||
+{
|
||||
+ char *key;
|
||||
+ char *group_dn_val;
|
||||
+ char *group_ndn_val;
|
||||
+ int valid;
|
||||
+} memberof_cached_value;
|
||||
|
||||
/*
|
||||
* functions
|
||||
@@ -89,5 +103,8 @@ int memberof_apply_config(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entr
|
||||
void *memberof_get_plugin_id(void);
|
||||
void memberof_release_config(void);
|
||||
PRUint64 get_plugin_started(void);
|
||||
+void ancestor_hashtable_entry_free(memberof_cached_value *entry);
|
||||
+PLHashTable *hashtable_new();
|
||||
+int memberof_use_txn();
|
||||
|
||||
#endif /* _MEMBEROF_H_ */
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c
|
||||
index c5ca4b137..3f22d95d6 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof_config.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof_config.c
|
||||
@@ -14,12 +14,12 @@
|
||||
* memberof_config.c - configuration-related code for memberOf plug-in
|
||||
*
|
||||
*/
|
||||
-
|
||||
+#include "plhash.h"
|
||||
#include <plstr.h>
|
||||
-
|
||||
#include "memberof.h"
|
||||
|
||||
#define MEMBEROF_CONFIG_FILTER "(objectclass=*)"
|
||||
+#define MEMBEROF_HASHTABLE_SIZE 1000
|
||||
|
||||
/*
|
||||
* The configuration attributes are contained in the plugin entry e.g.
|
||||
@@ -34,14 +34,16 @@
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
-static int memberof_validate_config(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e, int *returncode, char *returntext, void *arg);
|
||||
-static int
|
||||
-memberof_search(Slapi_PBlock *pb __attribute__((unused)),
|
||||
- Slapi_Entry *entryBefore __attribute__((unused)),
|
||||
- Slapi_Entry *e __attribute__((unused)),
|
||||
- int *returncode __attribute__((unused)),
|
||||
- char *returntext __attribute__((unused)),
|
||||
- void *arg __attribute__((unused)))
|
||||
+static void fixup_hashtable_empty( MemberOfConfig *config, char *msg);
|
||||
+static void ancestor_hashtable_empty(MemberOfConfig *config, char *msg);
|
||||
+static int memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
|
||||
+ int *returncode, char *returntext, void *arg);
|
||||
+static int memberof_search (Slapi_PBlock *pb __attribute__((unused)),
|
||||
+ Slapi_Entry* entryBefore __attribute__((unused)),
|
||||
+ Slapi_Entry* e __attribute__((unused)),
|
||||
+ int *returncode __attribute__((unused)),
|
||||
+ char *returntext __attribute__((unused)),
|
||||
+ void *arg __attribute__((unused)))
|
||||
{
|
||||
return SLAPI_DSE_CALLBACK_OK;
|
||||
}
|
||||
@@ -52,7 +54,7 @@ memberof_search(Slapi_PBlock *pb __attribute__((unused)),
|
||||
/* This is the main configuration which is updated from dse.ldif. The
|
||||
* config will be copied when it is used by the plug-in to prevent it
|
||||
* being changed out from under a running memberOf operation. */
|
||||
-static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+static MemberOfConfig theConfig = {0};
|
||||
static Slapi_RWLock *memberof_config_lock = 0;
|
||||
static int inited = 0;
|
||||
|
||||
@@ -693,6 +695,13 @@ void
|
||||
memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src)
|
||||
{
|
||||
if (dest && src) {
|
||||
+
|
||||
+ /* Allocate our caches here since we only copy the config at the start of an op */
|
||||
+ if (memberof_use_txn() == 1){
|
||||
+ dest->ancestors_cache = hashtable_new();
|
||||
+ dest->fixup_cache = hashtable_new();
|
||||
+ }
|
||||
+
|
||||
/* Check if the copy is already up to date */
|
||||
if (src->groupattrs) {
|
||||
int i = 0, j = 0;
|
||||
@@ -787,6 +796,14 @@ memberof_free_config(MemberOfConfig *config)
|
||||
slapi_ch_free_string(&config->memberof_attr);
|
||||
memberof_free_scope(&(config->entryScopes), &config->entryScopeCount);
|
||||
memberof_free_scope(&(config->entryScopeExcludeSubtrees), &config->entryExcludeScopeCount);
|
||||
+ if (config->fixup_cache) {
|
||||
+ fixup_hashtable_empty(config, "memberof_free_config empty fixup_entry_hastable");
|
||||
+ PL_HashTableDestroy(config->fixup_cache);
|
||||
+ }
|
||||
+ if (config->ancestors_cache) {
|
||||
+ ancestor_hashtable_empty(config, "memberof_free_config empty group_ancestors_hashtable");
|
||||
+ PL_HashTableDestroy(config->ancestors_cache);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -982,3 +999,130 @@ bail:
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+
|
||||
+static PRIntn memberof_hash_compare_keys(const void *v1, const void *v2)
|
||||
+{
|
||||
+ PRIntn rc;
|
||||
+ if (0 == strcasecmp((const char *) v1, (const char *) v2)) {
|
||||
+ rc = 1;
|
||||
+ } else {
|
||||
+ rc = 0;
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static PRIntn memberof_hash_compare_values(const void *v1, const void *v2)
|
||||
+{
|
||||
+ PRIntn rc;
|
||||
+ if ((char *) v1 == (char *) v2) {
|
||||
+ rc = 1;
|
||||
+ } else {
|
||||
+ rc = 0;
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Hashing function using Bernstein's method
|
||||
+ */
|
||||
+static PLHashNumber memberof_hash_fn(const void *key)
|
||||
+{
|
||||
+ PLHashNumber hash = 5381;
|
||||
+ unsigned char *x = (unsigned char *)key;
|
||||
+ int c;
|
||||
+
|
||||
+ while ((c = *x++)){
|
||||
+ hash = ((hash << 5) + hash) ^ c;
|
||||
+ }
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+/* allocates the plugin hashtable
|
||||
+ * This hash table is used by operation and is protected from
|
||||
+ * concurrent operations with the memberof_lock (if not usetxn, memberof_lock
|
||||
+ * is not implemented and the hash table will be not used.
|
||||
+ *
|
||||
+ * The hash table contains all the DN of the entries for which the memberof
|
||||
+ * attribute has been computed/updated during the current operation
|
||||
+ *
|
||||
+ * hash table should be empty at the beginning and end of the plugin callback
|
||||
+ */
|
||||
+PLHashTable *hashtable_new(int usetxn)
|
||||
+{
|
||||
+ if (!usetxn) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return PL_NewHashTable(MEMBEROF_HASHTABLE_SIZE,
|
||||
+ memberof_hash_fn,
|
||||
+ memberof_hash_compare_keys,
|
||||
+ memberof_hash_compare_values, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+/* this function called for each hash node during hash destruction */
|
||||
+static PRIntn fixup_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused)))
|
||||
+{
|
||||
+ char *dn_copy;
|
||||
+
|
||||
+ if (he == NULL) {
|
||||
+ return HT_ENUMERATE_NEXT;
|
||||
+ }
|
||||
+ dn_copy = (char*) he->value;
|
||||
+ slapi_ch_free_string(&dn_copy);
|
||||
+
|
||||
+ return HT_ENUMERATE_REMOVE;
|
||||
+}
|
||||
+
|
||||
+static void fixup_hashtable_empty(MemberOfConfig *config, char *msg)
|
||||
+{
|
||||
+ if (config->fixup_cache) {
|
||||
+ PL_HashTableEnumerateEntries(config->fixup_cache, fixup_hashtable_remove, msg);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* allocates the plugin hashtable
|
||||
+ * This hash table is used by operation and is protected from
|
||||
+ * concurrent operations with the memberof_lock (if not usetxn, memberof_lock
|
||||
+ * is not implemented and the hash table will be not used.
|
||||
+ *
|
||||
+ * The hash table contains all the DN of the entries for which the memberof
|
||||
+ * attribute has been computed/updated during the current operation
|
||||
+ *
|
||||
+ * hash table should be empty at the beginning and end of the plugin callback
|
||||
+ */
|
||||
+
|
||||
+void ancestor_hashtable_entry_free(memberof_cached_value *entry)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; entry[i].valid; i++) {
|
||||
+ slapi_ch_free((void **) &entry[i].group_dn_val);
|
||||
+ slapi_ch_free((void **) &entry[i].group_ndn_val);
|
||||
+ }
|
||||
+ /* Here we are at the ending element containing the key */
|
||||
+ slapi_ch_free((void**) &entry[i].key);
|
||||
+}
|
||||
+
|
||||
+/* this function called for each hash node during hash destruction */
|
||||
+static PRIntn ancestor_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused)))
|
||||
+{
|
||||
+ memberof_cached_value *group_ancestor_array;
|
||||
+
|
||||
+ if (he == NULL) {
|
||||
+ return HT_ENUMERATE_NEXT;
|
||||
+ }
|
||||
+ group_ancestor_array = (memberof_cached_value *) he->value;
|
||||
+ ancestor_hashtable_entry_free(group_ancestor_array);
|
||||
+ slapi_ch_free((void **)&group_ancestor_array);
|
||||
+
|
||||
+ return HT_ENUMERATE_REMOVE;
|
||||
+}
|
||||
+
|
||||
+static void ancestor_hashtable_empty(MemberOfConfig *config, char *msg)
|
||||
+{
|
||||
+ if (config->ancestors_cache) {
|
||||
+ PL_HashTableEnumerateEntries(config->ancestors_cache, ancestor_hashtable_remove, msg);
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From 1bb5fd7fac9c5b93d3dfb8b8a2a648e238a158bc Mon Sep 17 00:00:00 2001
|
||||
From de03e7456108de3f3d28c6a5d33926525b70557f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 30 Aug 2018 14:28:10 -0400
|
||||
Subject: [PATCH] Ticket 49932 - Crash in delete_passwdPolicy when persistent
|
|
@ -0,0 +1,99 @@
|
|||
From ab7848a4a30d79c7433a1689ba1ea18897b73453 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 18 Sep 2018 16:39:26 -0400
|
||||
Subject: [PATCH] Bug 1624004 - potential denial of service attack
|
||||
|
||||
Bug: a search request passing 8MB of NULL bytes as search attributes will
|
||||
keep one thread busy for a long time.
|
||||
The reason is that the attr array is copied/normalized to the searchattrs in
|
||||
the search operation and does this using charray_add() which iterates thru
|
||||
the array to determine the size of the array and then allocate one element more.
|
||||
so this means we iterat 8 million times an array with a then average size of
|
||||
4 million elements.
|
||||
|
||||
Fix: We already have traversed the array once and know the size, so we can allocate
|
||||
the needed size once and only copy the element.
|
||||
In addition we check for the kind of degenerated attributes "" as used in this
|
||||
test scenario.
|
||||
So the fix will reject invalid attr liste and improve performance for valid ones
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1624004
|
||||
---
|
||||
ldap/servers/slapd/search.c | 16 ++++++++++++++--
|
||||
ldap/servers/slapd/unbind.c | 4 ++--
|
||||
2 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
|
||||
index 731c6519e..dc26fc4d2 100644
|
||||
--- a/ldap/servers/slapd/search.c
|
||||
+++ b/ldap/servers/slapd/search.c
|
||||
@@ -209,6 +209,7 @@ do_search(Slapi_PBlock *pb)
|
||||
if (attrs != NULL) {
|
||||
char *normaci = slapi_attr_syntax_normalize("aci");
|
||||
int replace_aci = 0;
|
||||
+ int attr_count = 0;
|
||||
if (!normaci) {
|
||||
normaci = slapi_ch_strdup("aci");
|
||||
} else if (strcasecmp(normaci, "aci")) {
|
||||
@@ -218,9 +219,19 @@ do_search(Slapi_PBlock *pb)
|
||||
/*
|
||||
* . store gerattrs if any
|
||||
* . add "aci" once if "*" is given
|
||||
+ * . check that attrs are not degenerated
|
||||
*/
|
||||
for (i = 0; attrs[i] != NULL; i++) {
|
||||
char *p = NULL;
|
||||
+ attr_count++;
|
||||
+
|
||||
+ if ( attrs[i][0] == '\0') {
|
||||
+ log_search_access(pb, base, scope, fstr, "invalid attribute request");
|
||||
+ send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL);
|
||||
+ slapi_ch_free_string(&normaci);
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
+
|
||||
/* check if @<objectclass> is included */
|
||||
p = strchr(attrs[i], '@');
|
||||
if (p) {
|
||||
@@ -244,6 +255,7 @@ do_search(Slapi_PBlock *pb)
|
||||
} else if (strcmp(attrs[i], LDAP_ALL_USER_ATTRS /* '*' */) == 0) {
|
||||
if (!charray_inlist(attrs, normaci)) {
|
||||
charray_add(&attrs, slapi_ch_strdup(normaci));
|
||||
+ attr_count++;
|
||||
}
|
||||
} else if (replace_aci && (strcasecmp(attrs[i], "aci") == 0)) {
|
||||
slapi_ch_free_string(&attrs[i]);
|
||||
@@ -263,13 +275,13 @@ do_search(Slapi_PBlock *pb)
|
||||
}
|
||||
} else {
|
||||
/* return the chopped type, e.g., "sn" */
|
||||
- operation->o_searchattrs = NULL;
|
||||
+ operation->o_searchattrs = (char **)slapi_ch_calloc(sizeof(char *), attr_count+1);
|
||||
for (i = 0; attrs[i] != NULL; i++) {
|
||||
char *type;
|
||||
type = slapi_attr_syntax_normalize_ext(attrs[i],
|
||||
ATTR_SYNTAX_NORM_ORIG_ATTR);
|
||||
/* attrs[i] is consumed */
|
||||
- charray_add(&operation->o_searchattrs, attrs[i]);
|
||||
+ operation->o_searchattrs[i] = attrs[i];
|
||||
attrs[i] = type;
|
||||
}
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/unbind.c b/ldap/servers/slapd/unbind.c
|
||||
index 90f7b1546..686e27a8e 100644
|
||||
--- a/ldap/servers/slapd/unbind.c
|
||||
+++ b/ldap/servers/slapd/unbind.c
|
||||
@@ -87,8 +87,8 @@ do_unbind(Slapi_PBlock *pb)
|
||||
/* pass the unbind to all backends */
|
||||
be_unbindall(pb_conn, operation);
|
||||
|
||||
+free_and_return:;
|
||||
+
|
||||
/* close the connection to the client */
|
||||
disconnect_server(pb_conn, operation->o_connid, operation->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
||||
-
|
||||
-free_and_return:;
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From 23a82820bce65653f96450fcc410706fa555fbfd Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 16 Oct 2017 10:44:29 -0400
|
||||
Subject: [PATCH] Ticket 48235 - remove memberof lock (cherry-pick error)
|
||||
|
||||
Description: Fix cherry-pick error
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48235
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
|
||||
(cherry picked from commit 3eb443b0ee11f3cf642ebfbcd135868a72ce39da)
|
||||
---
|
||||
ldap/servers/plugins/memberof/memberof.c | 3 ---
|
||||
ldap/servers/plugins/memberof/memberof.h | 2 --
|
||||
2 files changed, 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index a23c52abe..bae242c81 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -2828,9 +2828,6 @@ memberof_fixup_task_thread(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
- /* get the memberOf operation lock */
|
||||
- memberof_lock();
|
||||
-
|
||||
/* do real work */
|
||||
rc = memberof_fix_memberof(&configCopy, task, td);
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
|
||||
index ba64e9dfa..cf028453c 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.h
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.h
|
||||
@@ -88,8 +88,6 @@ int memberof_config(Slapi_Entry *config_e, Slapi_PBlock *pb);
|
||||
void memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src);
|
||||
void memberof_free_config(MemberOfConfig *config);
|
||||
MemberOfConfig *memberof_get_config(void);
|
||||
-void memberof_lock(void);
|
||||
-void memberof_unlock(void);
|
||||
void memberof_rlock_config(void);
|
||||
void memberof_wlock_config(void);
|
||||
void memberof_unlock_config(void);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
From 55e961338810d89a6f45f31f27b3fd609535b1da Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 19 Sep 2018 09:26:59 -0400
|
||||
Subject: [PATCH] Bug 1624004 - fix regression in empty attribute list
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1624004
|
||||
---
|
||||
ldap/servers/slapd/search.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
|
||||
index dc26fc4d2..7e253f535 100644
|
||||
--- a/ldap/servers/slapd/search.c
|
||||
+++ b/ldap/servers/slapd/search.c
|
||||
@@ -210,6 +210,7 @@ do_search(Slapi_PBlock *pb)
|
||||
char *normaci = slapi_attr_syntax_normalize("aci");
|
||||
int replace_aci = 0;
|
||||
int attr_count = 0;
|
||||
+ int empty_attrs = 0;
|
||||
if (!normaci) {
|
||||
normaci = slapi_ch_strdup("aci");
|
||||
} else if (strcasecmp(normaci, "aci")) {
|
||||
@@ -226,10 +227,13 @@ do_search(Slapi_PBlock *pb)
|
||||
attr_count++;
|
||||
|
||||
if ( attrs[i][0] == '\0') {
|
||||
- log_search_access(pb, base, scope, fstr, "invalid attribute request");
|
||||
- send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL);
|
||||
- slapi_ch_free_string(&normaci);
|
||||
- goto free_and_return;
|
||||
+ empty_attrs++;
|
||||
+ if (empty_attrs > 1) {
|
||||
+ log_search_access(pb, base, scope, fstr, "invalid attribute request");
|
||||
+ send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL);
|
||||
+ slapi_ch_free_string(&normaci);
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* check if @<objectclass> is included */
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,703 +0,0 @@
|
|||
From 0b58d1a62679c3961bc41e03591c4277fb9f183e Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Thu, 5 Oct 2017 12:50:50 +0200
|
||||
Subject: [PATCH] Ticket 49394 - slapi_pblock_get may leave unchanged the
|
||||
provided variable
|
||||
|
||||
Bug Description:
|
||||
Since 1.3.6.4 the pblock struct is a split in sub-structs
|
||||
(https://pagure.io/389-ds-base/issue/49097)
|
||||
|
||||
Before, it was a quite flat calloc struct and any slapi-pblock-get
|
||||
retrieved the field (NULL if not previously slapi_pblock_set) and
|
||||
assigned the provided variable.
|
||||
|
||||
Now, the sub-struct are allocated on demand (slapi_pblock_set).
|
||||
If a substruct that contains the requested field is not allocated the
|
||||
provided variable is unchanged.
|
||||
|
||||
This is a change of behavior, because a uninitialized local variable can
|
||||
get random value (stack) if the lookup field/struct has not been set.
|
||||
|
||||
Fix Description:
|
||||
Update slapi_pblock_set so that it systematically sets the
|
||||
provided variable when those substructs are NULL
|
||||
pb_mr
|
||||
pb_dse
|
||||
pb_task
|
||||
pb_misc
|
||||
pb_intop
|
||||
pb_intplugin
|
||||
pb_deprecated
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49394
|
||||
|
||||
Reviewed by: Mark Reynolds, William Brown
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/pblock.c | 166 +++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 165 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
|
||||
index 077684d23..8f87de5b5 100644
|
||||
--- a/ldap/servers/slapd/pblock.c
|
||||
+++ b/ldap/servers/slapd/pblock.c
|
||||
@@ -379,6 +379,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_BACKEND_COUNT:
|
||||
if (pblock->pb_misc != NULL) {
|
||||
(*(int *)value) = pblock->pb_misc->pb_backend_count;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_BE_TYPE:
|
||||
@@ -616,6 +618,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_REQUESTOR_ISROOT:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(int *)value) = pblock->pb_intop->pb_requestor_isroot;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_SKIP_MODIFIED_ATTRS:
|
||||
@@ -657,6 +661,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DESTROY_CONTENT:
|
||||
if (pblock->pb_deprecated != NULL) {
|
||||
(*(int *)value) = pblock->pb_deprecated->pb_destroy_content;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -685,16 +691,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_OPRETURN:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(int *)value) = pblock->pb_intop->pb_opreturn;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_OBJECT:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(void **)value) = pblock->pb_intplugin->pb_object;
|
||||
+ } else {
|
||||
+ (*(void **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_DESTROY_FN:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_intplugin->pb_destroy_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_DESCRIPTION:
|
||||
@@ -703,11 +715,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_IDENTITY:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(void **)value) = pblock->pb_intplugin->pb_plugin_identity;
|
||||
+ } else {
|
||||
+ (*(void **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_CONFIG_AREA:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(char **)value) = pblock->pb_intplugin->pb_plugin_config_area;
|
||||
+ } else {
|
||||
+ (*(char **)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_CONFIG_DN:
|
||||
@@ -718,16 +734,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_INTOP_RESULT:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(int *)value) = pblock->pb_intop->pb_internal_op_result;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry ***)value) = pblock->pb_intop->pb_plugin_internal_search_op_entries;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(char ***)value) = pblock->pb_intop->pb_plugin_internal_search_op_referrals;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1167,11 +1189,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_ENTRY_PRE_OP:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_pre_op_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_ENTRY_POST_OP:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_post_op_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1419,12 +1445,16 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_CONTROLS_ARG: /* used to pass control argument before operation is created */
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(LDAPControl ***)value) = pblock->pb_intop->pb_ctrls_arg;
|
||||
+ } else {
|
||||
+ (*(LDAPControl ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
/* notes to be added to the access log RESULT line for this op. */
|
||||
case SLAPI_OPERATION_NOTES:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(unsigned int *)value) = pblock->pb_intop->pb_operation_notes;
|
||||
+ } else {
|
||||
+ (*(unsigned int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1486,6 +1516,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_SYNTAX_SUBSTRLENS: /* aka SLAPI_MR_SUBSTRLENS */
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(int **)value) = pblock->pb_intplugin->pb_substrlens;
|
||||
+ } else {
|
||||
+ (*(int **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_SYNTAX_VALIDATE:
|
||||
@@ -1505,11 +1537,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_MANAGEDSAIT:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(int *)value) = pblock->pb_intop->pb_managedsait;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PWPOLICY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(int *)value) = pblock->pb_intop->pb_pwpolicy_ctrl;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1522,11 +1558,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_ADD_EXISTING_DN_ENTRY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_existing_dn_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_ADD_EXISTING_UNIQUEID_ENTRY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_existing_uniqueid_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_ADD_PARENT_ENTRY:
|
||||
@@ -1537,6 +1577,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_ADD_PARENT_UNIQUEID:
|
||||
if (pblock->pb_op != NULL) {
|
||||
(*(char **)value) = pblock->pb_op->o_params.p.p_add.parentuniqueid;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1624,16 +1666,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_MODRDN_PARENT_ENTRY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_parent_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_MODRDN_NEWPARENT_ENTRY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_newparent_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_MODRDN_TARGET_ENTRY:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_intop->pb_target_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_MODRDN_NEWSUPERIOR_ADDRESS:
|
||||
@@ -1740,26 +1788,36 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_MR_FILTER_MATCH_FN:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(mrFilterMatchFn *)value) = pblock->pb_mr->filter_match_fn;
|
||||
+ } else {
|
||||
+ (*(mrFilterMatchFn *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_FILTER_INDEX_FN:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_mr->filter_index_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_FILTER_RESET_FN:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_mr->filter_reset_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_INDEX_FN:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_mr->index_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_INDEX_SV_FN:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_mr->index_sv_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1767,41 +1825,57 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_MR_OID:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(char **)value) = pblock->pb_mr->oid;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_TYPE:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(char **)value) = pblock->pb_mr->type;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_VALUE:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(struct berval **)value) = pblock->pb_mr->value;
|
||||
+ } else {
|
||||
+ (*(struct berval **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_VALUES:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(struct berval ***)value) = pblock->pb_mr->values;
|
||||
+ } else {
|
||||
+ (*(struct berval ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_KEYS:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(struct berval ***)value) = pblock->pb_mr->keys;
|
||||
+ } else {
|
||||
+ (*(struct berval ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_FILTER_REUSABLE:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(unsigned int *)value) = pblock->pb_mr->filter_reusable;
|
||||
+ } else {
|
||||
+ (*(unsigned int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_QUERY_OPERATOR:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(int *)value) = pblock->pb_mr->query_operator;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_PLUGIN_MR_USAGE:
|
||||
if (pblock->pb_mr != NULL) {
|
||||
(*(unsigned int *)value) = pblock->pb_mr->usage;
|
||||
+ } else {
|
||||
+ (*(unsigned int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1865,16 +1939,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_SEQ_TYPE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->seq_type;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_SEQ_ATTRNAME:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->seq_attrname;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_SEQ_VAL:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->seq_val;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1882,47 +1962,65 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_LDIF2DB_FILE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char ***)value) = pblock->pb_task->ldif_files;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_REMOVEDUPVALS:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->removedupvals;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_DB2INDEX_ATTRS:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char ***)value) = pblock->pb_task->db2index_attrs;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_NOATTRINDEXES:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->ldif2db_noattrindexes;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_INCLUDE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char ***)value) = pblock->pb_task->ldif_include;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_EXCLUDE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char ***)value) = pblock->pb_task->ldif_exclude;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_GENERATE_UNIQUEID:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->ldif_generate_uniqueid;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_ENCRYPT:
|
||||
case SLAPI_DB2LDIF_DECRYPT:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->ldif_encrypt;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_LDIF2DB_NAMESPACEID:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->ldif_namespaceid;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1930,16 +2028,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DB2LDIF_PRINTKEY:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->ldif_printkey;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_DB2LDIF_DUMP_UNIQUEID:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->ldif_dump_uniqueid;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_DB2LDIF_FILE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->ldif_file;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1947,37 +2051,51 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_BACKEND_INSTANCE_NAME:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->instance_name;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_BACKEND_TASK:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(Slapi_Task **)value) = pblock->pb_task->task;
|
||||
+ } else {
|
||||
+ (*(Slapi_Task **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_TASK_FLAGS:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->task_flags;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_DB2LDIF_SERVER_RUNNING:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->server_running;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_BULK_IMPORT_ENTRY:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(Slapi_Entry **)value) = pblock->pb_task->import_entry;
|
||||
+ } else {
|
||||
+ (*(Slapi_Entry **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_BULK_IMPORT_STATE:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(int *)value) = pblock->pb_task->import_state;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
/* dbverify */
|
||||
case SLAPI_DBVERIFY_DBDIR:
|
||||
if (pblock->pb_task != NULL) {
|
||||
(*(char **)value) = pblock->pb_task->dbverify_dbdir;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1993,11 +2111,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_TXN:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(void **)value) = pblock->pb_intop->pb_txn;
|
||||
+ } else {
|
||||
+ (*(void **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
case SLAPI_TXN_RUV_MODS_FN:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(IFP *)value) = pblock->pb_intop->pb_txn_ruv_mods_fn;
|
||||
+ } else {
|
||||
+ (*(IFP *)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2052,6 +2174,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PB_RESULT_TEXT:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
*((char **)value) = pblock->pb_intop->pb_result_text;
|
||||
+ } else {
|
||||
+ *((char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2059,6 +2183,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DBSIZE:
|
||||
if (pblock->pb_misc != NULL) {
|
||||
(*(unsigned int *)value) = pblock->pb_misc->pb_dbsize;
|
||||
+ } else {
|
||||
+ (*(unsigned int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2153,11 +2279,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_ARGC:
|
||||
if (pblock->pb_misc != NULL) {
|
||||
(*(int *)value) = pblock->pb_misc->pb_slapd_argc;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
case SLAPI_ARGV:
|
||||
if (pblock->pb_misc != NULL) {
|
||||
(*(char ***)value) = pblock->pb_misc->pb_slapd_argv;
|
||||
+ } else {
|
||||
+ (*(char ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2165,6 +2295,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_CONFIG_DIRECTORY:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(char **)value) = pblock->pb_intplugin->pb_slapd_configdir;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2175,12 +2307,16 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_PWD_STORAGE_SCHEME_USER_PWD:
|
||||
if (pblock->pb_deprecated != NULL) {
|
||||
(*(char **)value) = pblock->pb_deprecated->pb_pwd_storage_scheme_user_passwd;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_PLUGIN_PWD_STORAGE_SCHEME_DB_PWD:
|
||||
if (pblock->pb_deprecated != NULL) {
|
||||
(*(char **)value) = pblock->pb_deprecated->pb_pwd_storage_scheme_db_passwd;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2208,6 +2344,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_PLUGIN_ENABLED:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
*((int *)value) = pblock->pb_intplugin->pb_plugin_enabled;
|
||||
+ } else {
|
||||
+ *((int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2215,6 +2353,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DSE_DONT_WRITE_WHEN_ADDING:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->dont_add_write;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2222,6 +2362,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DSE_MERGE_WHEN_ADDING:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->add_merge;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2229,6 +2371,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DSE_DONT_CHECK_DUPS:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->dont_check_dups;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2236,6 +2380,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DSE_REAPPLY_MODS:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->reapply_mods;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2243,6 +2389,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_DSE_IS_PRIMARY_FILE:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->is_primary_file;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2250,42 +2398,56 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_SCHEMA_FLAGS:
|
||||
if (pblock->pb_dse != NULL) {
|
||||
(*(int *)value) = pblock->pb_dse->schema_flags;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_URP_NAMING_COLLISION_DN:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(char **)value) = pblock->pb_intop->pb_urp_naming_collision_dn;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_URP_TOMBSTONE_UNIQUEID:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(char **)value) = pblock->pb_intop->pb_urp_tombstone_uniqueid;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_URP_TOMBSTONE_CONFLICT_DN:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
- (*(char **)value) = pblock->pb_intop->pb_urp_tombstone_conflict_dn;
|
||||
+ (*(char **)value) = pblock->pb_intop->pb_urp_tombstone_conflict_dn;
|
||||
+ } else {
|
||||
+ (*(char **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_SEARCH_CTRLS:
|
||||
if (pblock->pb_intop != NULL) {
|
||||
(*(LDAPControl ***)value) = pblock->pb_intop->pb_search_ctrls;
|
||||
+ } else {
|
||||
+ (*(LDAPControl ***)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(int *)value) = pblock->pb_intplugin->pb_syntax_filter_normalized;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAPI_PLUGIN_SYNTAX_FILTER_DATA:
|
||||
if (pblock->pb_intplugin != NULL) {
|
||||
(*(void **)value) = pblock->pb_intplugin->pb_syntax_filter_data;
|
||||
+ } else {
|
||||
+ (*(void **)value) = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2311,6 +2473,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
case SLAPI_ACI_TARGET_CHECK:
|
||||
if (pblock->pb_misc != NULL) {
|
||||
(*(int *)value) = pblock->pb_misc->pb_aci_target_check;
|
||||
+ } else {
|
||||
+ (*(int *)value) = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
From 697e01b0ca2d028f0d2cabc47ab2335de93b0491 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 16 Oct 2017 12:52:46 -0400
|
||||
Subject: [PATCH] Ticket 49402 - Adding a database entry with the same database
|
||||
name that was deleted hangs server at shutdown
|
||||
|
||||
Bug Description: At shutdown, after a backend was deleted, which also had a import
|
||||
task run, the server hangs at shutdown. The issue is that the
|
||||
import task destructor used the ldbm inst struct to see if it was
|
||||
busy, but the inst was freed and the destructor was checking invalid
|
||||
memory which caused a false positive on the "busy" check.
|
||||
|
||||
Fix Description: Do not check if the instance is busy to tell if it's okay to remove
|
||||
the task, instead just check the task's state.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49402
|
||||
|
||||
Reviewed by: lkrispen(Thanks!)
|
||||
|
||||
(cherry picked from commit bc6dbf15c160ac7e6c553133b2b936a981cfb7b6)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/import.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c
|
||||
index e8f4a5615..42e2696d3 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/import.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/import.c
|
||||
@@ -244,7 +244,7 @@ import_task_destroy(Slapi_Task *task)
|
||||
return;
|
||||
}
|
||||
|
||||
- while (is_instance_busy(job->inst)) {
|
||||
+ while (task->task_state == SLAPI_TASK_RUNNING) {
|
||||
/* wait for the job to finish before freeing it */
|
||||
DS_Sleep(PR_SecondsToInterval(1));
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,332 +0,0 @@
|
|||
From 4af03a6a2a59684950d887d42c6e9d8b027d71f5 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Mon, 16 Oct 2017 11:21:51 +0200
|
||||
Subject: [PATCH] Ticket 49064 - RFE allow to enable MemberOf plugin in
|
||||
dedicated consumer
|
||||
|
||||
Bug Description:
|
||||
memberof triggers some internal updates to add/del 'memberof' values.
|
||||
on a readonly consumer, those updates selects a REFERRAL_ON_UPDATE backend
|
||||
and that is not followed by internal updates.
|
||||
At the end of the day, the update is rejected and if memberof plugin is enabled
|
||||
replication will stuck on that rejected update
|
||||
|
||||
Fix Description:
|
||||
internal updates from memberof need to bypassing referrals.
|
||||
So they flag internal updates SLAPI_OP_FLAG_BYPASS_REFERRALS, so that mtn_get_be
|
||||
(mapping tree selection) will not return the referrals.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49064
|
||||
|
||||
Reviewed by: Ludwig Krispenz, William Brown (thanks a LOT !)
|
||||
|
||||
Platforms tested: F23 (all tickets + basic suite)
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49064_test.py | 259 ++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/memberof/memberof.c | 6 +-
|
||||
2 files changed, 262 insertions(+), 3 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49064_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49064_test.py b/dirsrvtests/tests/tickets/ticket49064_test.py
|
||||
new file mode 100644
|
||||
index 000000000..b4b6de4b9
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49064_test.py
|
||||
@@ -0,0 +1,259 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import time
|
||||
+import ldap
|
||||
+import subprocess
|
||||
+from lib389.utils import ds_is_older
|
||||
+from lib389.topologies import topology_m1h1c1 as topo
|
||||
+from lib389._constants import *
|
||||
+from lib389 import Entry
|
||||
+
|
||||
+# Skip on older versions
|
||||
+pytestmark = pytest.mark.skipif(ds_is_older('1.3.7'), reason="Not implemented")
|
||||
+
|
||||
+USER_CN='user_'
|
||||
+GROUP_CN='group_'
|
||||
+FIXUP_FILTER = '(objectClass=*)'
|
||||
+FIXUP_CMD = 'fixup-memberof.pl'
|
||||
+
|
||||
+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__)
|
||||
+
|
||||
+def memberof_fixup_task(server):
|
||||
+ sbin_dir = server.get_sbin_dir()
|
||||
+ memof_task = os.path.join(sbin_dir, FIXUP_CMD)
|
||||
+ try:
|
||||
+ output = subprocess.check_output(
|
||||
+ [memof_task, '-D', DN_DM, '-w', PASSWORD, '-b', SUFFIX, '-Z', SERVERID_CONSUMER_1, '-f', FIXUP_FILTER])
|
||||
+ except subprocess.CalledProcessError as err:
|
||||
+ output = err.output
|
||||
+ log.info('output: {}'.format(output))
|
||||
+ expected = "Successfully added task entry"
|
||||
+ assert expected in output
|
||||
+
|
||||
+def config_memberof(server):
|
||||
+
|
||||
+ server.plugins.enable(name=PLUGIN_MEMBER_OF)
|
||||
+ MEMBEROF_PLUGIN_DN = ('cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config')
|
||||
+ server.modify_s(MEMBEROF_PLUGIN_DN, [(ldap.MOD_REPLACE,
|
||||
+ 'memberOfAllBackends',
|
||||
+ 'on'),
|
||||
+ (ldap.MOD_REPLACE, 'memberOfAutoAddOC', 'nsMemberOf')])
|
||||
+ # Configure fractional to prevent total init to send memberof
|
||||
+ ents = server.agreement.list(suffix=DEFAULT_SUFFIX)
|
||||
+ for ent in ents:
|
||||
+ log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % ent.dn)
|
||||
+ server.modify_s(ent.dn,
|
||||
+ [(ldap.MOD_REPLACE,
|
||||
+ 'nsDS5ReplicatedAttributeListTotal',
|
||||
+ '(objectclass=*) $ EXCLUDE '),
|
||||
+ (ldap.MOD_REPLACE,
|
||||
+ 'nsDS5ReplicatedAttributeList',
|
||||
+ '(objectclass=*) $ EXCLUDE memberOf')])
|
||||
+
|
||||
+
|
||||
+def send_updates_now(server):
|
||||
+
|
||||
+ ents = server.agreement.list(suffix=DEFAULT_SUFFIX)
|
||||
+ for ent in ents:
|
||||
+ server.agreement.pause(ent.dn)
|
||||
+ server.agreement.resume(ent.dn)
|
||||
+
|
||||
+def add_user(server, no, desc='dummy', sleep=True):
|
||||
+ cn = '%s%d' % (USER_CN, no)
|
||||
+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
|
||||
+ log.fatal('Adding user (%s): ' % dn)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser'],
|
||||
+ 'sn': ['_%s' % cn],
|
||||
+ 'description': [desc]})))
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def add_group(server, nr, sleep=True):
|
||||
+ cn = '%s%d' % (GROUP_CN, nr)
|
||||
+ dn = 'cn=%s,ou=groups,%s' % (cn, SUFFIX)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'],
|
||||
+ 'description': 'group %d' % nr})))
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def update_member(server, member_dn, group_dn, op, sleep=True):
|
||||
+ mod = [(op, 'member', member_dn)]
|
||||
+ server.modify_s(group_dn, mod)
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def _find_memberof(server, member_dn, group_dn, find_result=True):
|
||||
+ ent = server.getEntry(member_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof'])
|
||||
+ found = False
|
||||
+ if ent.hasAttr('memberof'):
|
||||
+
|
||||
+ for val in ent.getValues('memberof'):
|
||||
+ server.log.info("!!!!!!! %s: memberof->%s" % (member_dn, val))
|
||||
+ server.log.info("!!!!!!! %s" % (val))
|
||||
+ server.log.info("!!!!!!! %s" % (group_dn))
|
||||
+ if val.lower() == group_dn.lower():
|
||||
+ found = True
|
||||
+ break
|
||||
+
|
||||
+ if find_result:
|
||||
+ assert (found)
|
||||
+ else:
|
||||
+ assert (not found)
|
||||
+
|
||||
+
|
||||
+def test_ticket49064(topo):
|
||||
+ """Specify a test case purpose or name here
|
||||
+
|
||||
+ :id: 60c11636-55a1-4704-9e09-2c6bcc828de4
|
||||
+ :setup: 1 Master - 1 Hub - 1 Consumer
|
||||
+ :steps:
|
||||
+ 1. Configure replication to EXCLUDE memberof
|
||||
+ 2. Enable memberof plugin
|
||||
+ 3. Create users/groups
|
||||
+ 4. make user_1 member of group_1
|
||||
+ 5. Checks that user_1 is memberof group_1 on M,H,C
|
||||
+ 6. make group_1 member of group_2 (nest group)
|
||||
+ 7. Checks that user_1 is memberof group_1 and group_2 on M,H,C
|
||||
+ 8. Check group_1 is memberof group_2 on M,H,C
|
||||
+ 9. remove group_1 from group_2
|
||||
+ 10. Check group_1 and user_1 are NOT memberof group_2 on M,H,C
|
||||
+ 11. remove user_1 from group_1
|
||||
+ 12. Check user_1 is NOT memberof group_1 and group_2 on M,H,C
|
||||
+ 13. Disable memberof on C1
|
||||
+ 14. make user_1 member of group_1
|
||||
+ 15. Checks that user is memberof group_1 on M,H but not on C
|
||||
+ 16. Enable memberof on C1
|
||||
+ 17. Checks that user is memberof group_1 on M,H but not on C
|
||||
+ 18. Run memberof fixup task
|
||||
+ 19. Checks that user is memberof group_1 on M,H,C
|
||||
+
|
||||
+
|
||||
+ :expectedresults:
|
||||
+ no assert for membership check
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+ M1 = topo.ms["master1"]
|
||||
+ H1 = topo.hs["hub1"]
|
||||
+ C1 = topo.cs["consumer1"]
|
||||
+
|
||||
+ # Step 1 & 2
|
||||
+ M1.config.enable_log('audit')
|
||||
+ config_memberof(M1)
|
||||
+ M1.restart()
|
||||
+
|
||||
+ H1.config.enable_log('audit')
|
||||
+ config_memberof(H1)
|
||||
+ H1.restart()
|
||||
+
|
||||
+ C1.config.enable_log('audit')
|
||||
+ config_memberof(C1)
|
||||
+ C1.restart()
|
||||
+
|
||||
+ # Step 3
|
||||
+ for i in range(10):
|
||||
+ add_user(M1, i, desc='add on m1')
|
||||
+ for i in range(3):
|
||||
+ add_group(M1, i)
|
||||
+
|
||||
+ # Step 4
|
||||
+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
|
||||
+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
|
||||
+ update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True)
|
||||
+
|
||||
+ # Step 5
|
||||
+ for i in [M1, H1, C1]:
|
||||
+ _find_memberof(i, member_dn, group_dn, find_result=True)
|
||||
+
|
||||
+
|
||||
+ # Step 6
|
||||
+ user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
|
||||
+ grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
|
||||
+ grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX)
|
||||
+ update_member(M1, grp1_dn, grp2_dn, ldap.MOD_ADD, sleep=True)
|
||||
+
|
||||
+ # Step 7
|
||||
+ for i in [grp1_dn, grp2_dn]:
|
||||
+ for inst in [M1, H1, C1]:
|
||||
+ _find_memberof(inst, user_dn, i, find_result=True)
|
||||
+
|
||||
+ # Step 8
|
||||
+ for i in [M1, H1, C1]:
|
||||
+ _find_memberof(i, grp1_dn, grp2_dn, find_result=True)
|
||||
+
|
||||
+ # Step 9
|
||||
+ user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
|
||||
+ grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
|
||||
+ grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX)
|
||||
+ update_member(M1, grp1_dn, grp2_dn, ldap.MOD_DELETE, sleep=True)
|
||||
+
|
||||
+ # Step 10
|
||||
+ for inst in [M1, H1, C1]:
|
||||
+ for i in [grp1_dn, user_dn]:
|
||||
+ _find_memberof(inst, i, grp2_dn, find_result=False)
|
||||
+
|
||||
+ # Step 11
|
||||
+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
|
||||
+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
|
||||
+ update_member(M1, member_dn, group_dn, ldap.MOD_DELETE, sleep=True)
|
||||
+
|
||||
+ # Step 12
|
||||
+ for inst in [M1, H1, C1]:
|
||||
+ for grp in [grp1_dn, grp2_dn]:
|
||||
+ _find_memberof(inst, member_dn, grp, find_result=False)
|
||||
+
|
||||
+ # Step 13
|
||||
+ C1.plugins.disable(name=PLUGIN_MEMBER_OF)
|
||||
+ C1.restart()
|
||||
+
|
||||
+ # Step 14
|
||||
+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
|
||||
+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
|
||||
+ update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True)
|
||||
+
|
||||
+ # Step 15
|
||||
+ for i in [M1, H1]:
|
||||
+ _find_memberof(i, member_dn, group_dn, find_result=True)
|
||||
+ _find_memberof(C1, member_dn, group_dn, find_result=False)
|
||||
+
|
||||
+ # Step 16
|
||||
+ C1.plugins.enable(name=PLUGIN_MEMBER_OF)
|
||||
+ C1.restart()
|
||||
+
|
||||
+ # Step 17
|
||||
+ for i in [M1, H1]:
|
||||
+ _find_memberof(i, member_dn, group_dn, find_result=True)
|
||||
+ _find_memberof(C1, member_dn, group_dn, find_result=False)
|
||||
+
|
||||
+ # Step 18
|
||||
+ memberof_fixup_task(C1)
|
||||
+ time.sleep(5)
|
||||
+
|
||||
+ # Step 19
|
||||
+ for i in [M1, H1, C1]:
|
||||
+ _find_memberof(i, member_dn, group_dn, find_result=True)
|
||||
+
|
||||
+ # If you need any test suite initialization,
|
||||
+ # please, write additional fixture for that (including finalizer).
|
||||
+ # Topology for suites are predefined in lib389/topologies.py.
|
||||
+
|
||||
+ # If you need host, port or any other data about instance,
|
||||
+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
|
||||
+
|
||||
+ if DEBUGGING:
|
||||
+ # Add debugging steps(if any)...
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index bae242c81..44b52edbb 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -609,7 +609,7 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
|
||||
slapi_modify_internal_set_pb_ext(
|
||||
mod_pb, slapi_entry_get_sdn(e),
|
||||
mods, 0, 0,
|
||||
- memberof_get_plugin_id(), 0);
|
||||
+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS);
|
||||
|
||||
slapi_modify_internal_pb(mod_pb);
|
||||
|
||||
@@ -3224,7 +3224,7 @@ memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc)
|
||||
mod_pb = slapi_pblock_new();
|
||||
slapi_modify_internal_set_pb(
|
||||
mod_pb, dn, mods, 0, 0,
|
||||
- memberof_get_plugin_id(), 0);
|
||||
+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS);
|
||||
slapi_modify_internal_pb(mod_pb);
|
||||
|
||||
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
||||
@@ -3279,7 +3279,7 @@ memberof_add_objectclass(char *auto_add_oc, const char *dn)
|
||||
|
||||
slapi_modify_internal_set_pb(
|
||||
mod_pb, dn, mods, 0, 0,
|
||||
- memberof_get_plugin_id(), 0);
|
||||
+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS);
|
||||
slapi_modify_internal_pb(mod_pb);
|
||||
|
||||
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From 82e092e9debce16f048b4fe0f38265bc8d80f63d Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Thu, 28 Sep 2017 09:11:00 +1000
|
||||
Subject: [PATCH] Ticket 49378 server init fails
|
||||
|
||||
Bug Description: We used our own target for DS installation, but
|
||||
we should just use multi-user like anything else.
|
||||
|
||||
Fix Description: Change service template to multi-user. This should
|
||||
be a seamless upgrade to most consumers.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49378
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit e9ad5f5aca64f65fa2c9b2dc5132b0dacf131c99)
|
||||
---
|
||||
wrappers/systemd.template.asan.service.in | 2 +-
|
||||
wrappers/systemd.template.service.in | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/wrappers/systemd.template.asan.service.in b/wrappers/systemd.template.asan.service.in
|
||||
index 1fe321ccb..52681f632 100644
|
||||
--- a/wrappers/systemd.template.asan.service.in
|
||||
+++ b/wrappers/systemd.template.asan.service.in
|
||||
@@ -36,5 +36,5 @@ ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/
|
||||
.include @initconfigdir@/@package_name@.systemd
|
||||
|
||||
[Install]
|
||||
-WantedBy=dirsrv.target
|
||||
+WantedBy=multi-user.target
|
||||
|
||||
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
|
||||
index 30b9e4b78..0d88900b6 100644
|
||||
--- a/wrappers/systemd.template.service.in
|
||||
+++ b/wrappers/systemd.template.service.in
|
||||
@@ -40,5 +40,5 @@ ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/
|
||||
.include @initconfigdir@/@package_name@.systemd
|
||||
|
||||
[Install]
|
||||
-WantedBy=dirsrv.target
|
||||
+WantedBy=multi-user.target
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From 9369164f45ba19519158286590aaefae1c64ef05 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Thu, 5 Oct 2017 09:54:48 +1000
|
||||
Subject: [PATCH] Ticket 49392 - memavailable not available
|
||||
|
||||
Bug Description: On certain linux platforms memAvailable is
|
||||
not actually available! This means that the value was 0, so
|
||||
cgroup max was read instead, setting the system ram to:
|
||||
|
||||
9223372036854771712
|
||||
|
||||
That's a bit excessive, and can cause memory allocations to fail.
|
||||
|
||||
Fix Description: If memavail can't be found, fall back to
|
||||
memtotal instead.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49392
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/slapi_pal.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/slapi_pal.c b/ldap/servers/slapd/slapi_pal.c
|
||||
index 38c178cfa..600d03d4d 100644
|
||||
--- a/ldap/servers/slapd/slapi_pal.c
|
||||
+++ b/ldap/servers/slapd/slapi_pal.c
|
||||
@@ -155,7 +155,16 @@ spal_meminfo_get()
|
||||
|
||||
/* Both memtotal and memavail are in kb */
|
||||
memtotal = memtotal * 1024;
|
||||
- memavail = memavail * 1024;
|
||||
+
|
||||
+ /*
|
||||
+ * Oracle Enterprise Linux doesn't provide a valid memavail value, so fall
|
||||
+ * back to 80% of memtotal.
|
||||
+ */
|
||||
+ if (memavail == 0) {
|
||||
+ memavail = memtotal * 0.8;
|
||||
+ } else {
|
||||
+ memavail = memavail * 1024;
|
||||
+ }
|
||||
|
||||
/* If it's possible, get our cgroup info */
|
||||
uint64_t cg_mem_soft = 0;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
From 73c72aba0ab31f9d16cdfd8879e9da5f3fb985e0 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 17 Oct 2017 12:39:18 -0400
|
||||
Subject: [PATCH] Ticket 48006 - Missing warning for invalid replica backoff
|
||||
configuration
|
||||
|
||||
Description: Add warning if you try to set a min backoff time that is
|
||||
greater than the configured maximum, or the max time that
|
||||
is less than the minimum.
|
||||
|
||||
Also fixed compiler warning in ldbm_config.c
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48006
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit e123acb6987c75f6d7282b32c4f279b976eb6f5e)
|
||||
---
|
||||
.../plugins/replication/repl5_replica_config.c | 24 ++++++++++++++++++++--
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 +-
|
||||
2 files changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index f28044c19..22d766143 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -465,7 +465,8 @@ replica_config_modify(Slapi_PBlock *pb,
|
||||
}
|
||||
} else if (strcasecmp(config_attr, type_replicaBackoffMin) == 0) {
|
||||
if (apply_mods) {
|
||||
- PRUint64 val = atoll(config_attr_value);
|
||||
+ uint64_t val = atoll(config_attr_value);
|
||||
+ uint64_t max;
|
||||
|
||||
if (val <= 0) {
|
||||
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||
@@ -475,11 +476,21 @@ replica_config_modify(Slapi_PBlock *pb,
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
|
||||
break;
|
||||
}
|
||||
+ max = replica_get_backoff_max(r);
|
||||
+ if (val > max){
|
||||
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n",
|
||||
+ config_attr, config_attr_value, (int)max);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
|
||||
+ break;
|
||||
+ }
|
||||
replica_set_backoff_min(r, val);
|
||||
}
|
||||
} else if (strcasecmp(config_attr, type_replicaBackoffMax) == 0) {
|
||||
if (apply_mods) {
|
||||
- PRUint64 val = atoll(config_attr_value);
|
||||
+ uint64_t val = atoll(config_attr_value);
|
||||
+ uint64_t min;
|
||||
|
||||
if (val <= 0) {
|
||||
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||
@@ -490,6 +501,15 @@ replica_config_modify(Slapi_PBlock *pb,
|
||||
errortext);
|
||||
break;
|
||||
}
|
||||
+ min = replica_get_backoff_min(r);
|
||||
+ if (val < min) {
|
||||
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n",
|
||||
+ config_attr, config_attr_value, (int)min);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
|
||||
+ break;
|
||||
+ }
|
||||
replica_set_backoff_max(r, val);
|
||||
}
|
||||
} else if (strcasecmp(config_attr, type_replicaPrecisePurge) == 0) {
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index 2ef4652ce..feb993366 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -388,7 +388,7 @@ ldbm_config_directory_set(void *arg, void *value, char *errorbuf, int phase, int
|
||||
goto done;
|
||||
}
|
||||
slapi_pblock_destroy(search_pb);
|
||||
- if (NULL == s || '\0' == s || 0 == PL_strcmp(s, "(null)")) {
|
||||
+ if (NULL == s || '\0' == *s || 0 == PL_strcmp(s, "(null)")) {
|
||||
slapi_log_err(SLAPI_LOG_ERR,
|
||||
"ldbm_config_directory_set", "db directory is not set; check %s in the db config: %s\n",
|
||||
CONFIG_DIRECTORY, CONFIG_LDBM_DN);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
From 4569da8f2c55d54a34f31312ee5756c70a7f463c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 19 Oct 2017 17:33:10 -0400
|
||||
Subject: [PATCH] Ticket 49408 - Server allows to set any nsds5replicaid in the
|
||||
existing replica entry
|
||||
|
||||
Description: There was no value validation for replica ID. Now there is.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49408
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 296f0abb78b7ec82580d039d9c505506f6ce07be)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica_config.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 22d766143..7477a292c 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -411,6 +411,18 @@ replica_config_modify(Slapi_PBlock *pb,
|
||||
slapi_ch_free_string(&new_repl_type);
|
||||
new_repl_type = slapi_ch_strdup(config_attr_value);
|
||||
} else if (strcasecmp(config_attr, attr_replicaId) == 0) {
|
||||
+ char *endp = NULL;
|
||||
+ int64_t rid = 0;
|
||||
+ errno = 0;
|
||||
+ rid = strtoll(config_attr_value, &endp, 10);
|
||||
+ if (*endp != '\0' || rid > 65535 || rid < 1 || errno == ERANGE) {
|
||||
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
||||
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Attribute %s value (%s) is invalid, must be a number between 1 and 65535.\n",
|
||||
+ config_attr, config_attr_value);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext);
|
||||
+ break;
|
||||
+ }
|
||||
slapi_ch_free_string(&new_repl_id);
|
||||
new_repl_id = slapi_ch_strdup(config_attr_value);
|
||||
} else if (strcasecmp(config_attr, attr_flags) == 0) {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From 70d236dedadc030fd2b450d7607b395b50523538 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 19 Oct 2017 17:02:20 -0400
|
||||
Subject: [PATCH] Ticket 49407 - status-dirsrv shows ellipsed lines
|
||||
|
||||
Bug Description: To show the full output you have to pass "-l" to systemctl,
|
||||
but there is no way to use this option with the current design.
|
||||
|
||||
Fix Description: Just show the full lines by default, as adding options can break
|
||||
the script's current usage.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49407
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 45d2fd4b50227687ad042a0e17d8dcd9e4cd3023)
|
||||
---
|
||||
ldap/admin/src/scripts/status-dirsrv.in | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/status-dirsrv.in b/ldap/admin/src/scripts/status-dirsrv.in
|
||||
index 90428990b..8e492c115 100755
|
||||
--- a/ldap/admin/src/scripts/status-dirsrv.in
|
||||
+++ b/ldap/admin/src/scripts/status-dirsrv.in
|
||||
@@ -37,7 +37,7 @@ status_instance() {
|
||||
# Use systemctl if available.
|
||||
#
|
||||
if [ -d "@systemdsystemunitdir@" ] && [ $(id -u) -eq 0 ];then
|
||||
- @bindir@/systemctl status @package_name@@$SERV_ID.service
|
||||
+ @bindir@/systemctl status @package_name@@$SERV_ID.service -l
|
||||
rv=$?
|
||||
if [ $rv -ne 0 ]; then
|
||||
return 1
|
||||
@@ -65,7 +65,7 @@ found=0
|
||||
if [ $# -eq 0 ]; then
|
||||
# We're reporting the status of all instances.
|
||||
ret=0
|
||||
- @bindir@/systemctl status @package_name@.target
|
||||
+ @bindir@/systemctl status @package_name@.target -l
|
||||
initfiles=`get_initconfig_files $initconfig_dir` || { echo No instances found in $initconfig_dir ; exit 1 ; }
|
||||
for i in $initfiles; do
|
||||
inst=`normalize_server_id $i`
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From b7cca69de5f6cda32bc38504a7aa7e5bc786bbe6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 19 Oct 2017 14:44:38 -0400
|
||||
Subject: [PATCH] Ticket 48681 - Use of uninitialized value in string ne at
|
||||
/usr/bin/logconv.pl line 2565, <$LOGFH> line 4
|
||||
|
||||
Bug description: The original fix for 48681 added a regression in regards to perl
|
||||
warning everytime you ran the script. That was due to a new hash
|
||||
for sasl binds that was not initialized.
|
||||
|
||||
Fix Description: Check is the saslbind hash "exists" before checking its value.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48681
|
||||
|
||||
Reviewed by: mreynolds (one line fix)
|
||||
|
||||
(cherry picked from commit e46749b77d95ad8fedf07d38890573b2862badf7)
|
||||
---
|
||||
ldap/admin/src/logconv.pl | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
|
||||
index 4932db42e..473c71f21 100755
|
||||
--- a/ldap/admin/src/logconv.pl
|
||||
+++ b/ldap/admin/src/logconv.pl
|
||||
@@ -2562,7 +2562,7 @@ sub parseLineNormal
|
||||
if ($_ =~ /conn= *([0-9A-Z]+) +op= *([0-9\-]+)/i){
|
||||
$conn = $1;
|
||||
$op = $2;
|
||||
- if ($hashes->{saslconnop}->{$conn-$op} ne ""){
|
||||
+ if (exists $hashes->{saslconnop}->{$conn-$op} && $hashes->{saslconnop}->{$conn-$op} ne ""){
|
||||
# This was a SASL BIND - record the dn
|
||||
if ($binddn ne ""){
|
||||
if($binddn eq $rootDN){ $rootDNBindCount++; }
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
From 4ecec8dac601b77a25ebc390f138aad1ee48d805 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 19 Oct 2017 12:20:48 -0400
|
||||
Subject: [PATCH] Ticket 49374 - server fails to start because maxdisksize is
|
||||
recognized incorrectly
|
||||
|
||||
Bug Description: When directly editting dse.ldif, the server had a check
|
||||
when setting the log maxdiskspace vs maxlogsize. If the
|
||||
maxlogsize is processed first and it is higher than the
|
||||
default maxdisksspace then it throw an error and the server
|
||||
fails to start.
|
||||
|
||||
If you attempt this same operation using ldapmodify it
|
||||
works as "live" updates check all the mods first, so the
|
||||
order of the attributes does not matter.
|
||||
|
||||
Fix description: Remove the size checks from the attribute set function.
|
||||
It is technically redundant since it is correctly checked
|
||||
by the configdse code.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49374
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 63a0a59c9b09af08151831209ee6711b4363aee2)
|
||||
---
|
||||
ldap/servers/slapd/log.c | 60 ++++++++++++------------------------------------
|
||||
1 file changed, 15 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
|
||||
index e16d89cc5..998efaef3 100644
|
||||
--- a/ldap/servers/slapd/log.c
|
||||
+++ b/ldap/servers/slapd/log.c
|
||||
@@ -960,7 +960,6 @@ int
|
||||
log_set_logsize(const char *attrname, char *logsize_str, int logtype, char *returntext, int apply)
|
||||
{
|
||||
int rv = LDAP_SUCCESS;
|
||||
- PRInt64 mdiskspace = 0; /* in bytes */
|
||||
PRInt64 max_logsize; /* in bytes */
|
||||
int logsize; /* in megabytes */
|
||||
slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
|
||||
@@ -979,72 +978,43 @@ log_set_logsize(const char *attrname, char *logsize_str, int logtype, char *retu
|
||||
|
||||
switch (logtype) {
|
||||
case SLAPD_ACCESS_LOG:
|
||||
- LOG_ACCESS_LOCK_WRITE();
|
||||
- mdiskspace = loginfo.log_access_maxdiskspace;
|
||||
- break;
|
||||
- case SLAPD_ERROR_LOG:
|
||||
- LOG_ERROR_LOCK_WRITE();
|
||||
- mdiskspace = loginfo.log_error_maxdiskspace;
|
||||
- break;
|
||||
- case SLAPD_AUDIT_LOG:
|
||||
- LOG_AUDIT_LOCK_WRITE();
|
||||
- mdiskspace = loginfo.log_audit_maxdiskspace;
|
||||
- break;
|
||||
- case SLAPD_AUDITFAIL_LOG:
|
||||
- LOG_AUDITFAIL_LOCK_WRITE();
|
||||
- mdiskspace = loginfo.log_auditfail_maxdiskspace;
|
||||
- break;
|
||||
- default:
|
||||
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
- "%s: invalid logtype %d", attrname, logtype);
|
||||
- rv = LDAP_OPERATIONS_ERROR;
|
||||
- }
|
||||
-
|
||||
- if ((max_logsize > mdiskspace) && (mdiskspace != -1)) {
|
||||
- rv = 2;
|
||||
- }
|
||||
-
|
||||
- switch (logtype) {
|
||||
- case SLAPD_ACCESS_LOG:
|
||||
- if (!rv && apply) {
|
||||
+ if (apply) {
|
||||
+ LOG_ACCESS_LOCK_WRITE();
|
||||
loginfo.log_access_maxlogsize = max_logsize;
|
||||
fe_cfg->accesslog_maxlogsize = logsize;
|
||||
+ LOG_ACCESS_UNLOCK_WRITE();
|
||||
}
|
||||
- LOG_ACCESS_UNLOCK_WRITE();
|
||||
break;
|
||||
case SLAPD_ERROR_LOG:
|
||||
- if (!rv && apply) {
|
||||
+ if (apply) {
|
||||
+ LOG_ERROR_LOCK_WRITE();
|
||||
loginfo.log_error_maxlogsize = max_logsize;
|
||||
fe_cfg->errorlog_maxlogsize = logsize;
|
||||
+ LOG_ERROR_UNLOCK_WRITE();
|
||||
}
|
||||
- LOG_ERROR_UNLOCK_WRITE();
|
||||
break;
|
||||
case SLAPD_AUDIT_LOG:
|
||||
- if (!rv && apply) {
|
||||
+ if (apply) {
|
||||
+ LOG_AUDIT_LOCK_WRITE();
|
||||
loginfo.log_audit_maxlogsize = max_logsize;
|
||||
fe_cfg->auditlog_maxlogsize = logsize;
|
||||
+ LOG_AUDIT_UNLOCK_WRITE();
|
||||
}
|
||||
- LOG_AUDIT_UNLOCK_WRITE();
|
||||
break;
|
||||
case SLAPD_AUDITFAIL_LOG:
|
||||
- if (!rv && apply) {
|
||||
+ if (apply) {
|
||||
+ LOG_AUDITFAIL_LOCK_WRITE();
|
||||
loginfo.log_auditfail_maxlogsize = max_logsize;
|
||||
fe_cfg->auditfaillog_maxlogsize = logsize;
|
||||
+ LOG_AUDITFAIL_UNLOCK_WRITE();
|
||||
}
|
||||
- LOG_AUDITFAIL_UNLOCK_WRITE();
|
||||
break;
|
||||
default:
|
||||
- rv = 1;
|
||||
- }
|
||||
- /* logsize is in MB */
|
||||
- if (rv == 2) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "log_set_logsize",
|
||||
- "Invalid value for Maximum log size:"
|
||||
- "Maxlogsize:%d (MB) exceeds Maxdisksize:%ld (MB)\n",
|
||||
- logsize, (long int)(mdiskspace / LOG_MB_IN_BYTES));
|
||||
-
|
||||
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "%s: invalid logtype %d", attrname, logtype);
|
||||
rv = LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
+
|
||||
return rv;
|
||||
}
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From ef4ac2d45c9ea99fbb1ae6cee97745161f193bf9 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 25 Oct 2017 10:53:28 -0400
|
||||
Subject: [PATCH] Ticket 48681 - Use of uninitialized value in string ne at
|
||||
/usr/bin/logconv.pl
|
||||
|
||||
Bug Description: ldapi connections were not properly porcessed by the
|
||||
connection parsing code which lead to uninitialized errors.
|
||||
|
||||
Fix Description: Modify the connection IP address regex's to include "local"
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48681
|
||||
|
||||
Reviewd by: mreynolds (one line commit rule)
|
||||
|
||||
(cherry picked from commit 6098e7b927b64ba300567e71ea611140c47676a1)
|
||||
---
|
||||
ldap/admin/src/logconv.pl | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
|
||||
index 473c71f21..e36386e11 100755
|
||||
--- a/ldap/admin/src/logconv.pl
|
||||
+++ b/ldap/admin/src/logconv.pl
|
||||
@@ -809,9 +809,9 @@ if ($totalTimeInNsecs == 0){
|
||||
print "Restarts: $serverRestartCount\n";
|
||||
|
||||
if(%cipher){
|
||||
- print " Secure Protocol Versions:\n";
|
||||
+ print "Secure Protocol Versions:\n";
|
||||
foreach my $key (sort { $b cmp $a } keys %cipher) {
|
||||
- print " - $key - $cipher{$key}\n";
|
||||
+ print " - $key ($cipher{$key} connections)\n";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
@@ -1754,7 +1754,7 @@ parseLineBind {
|
||||
($end) = $endTime =~ /\D*(\S*)/;
|
||||
}
|
||||
}
|
||||
- if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ) {
|
||||
+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ) {
|
||||
my $skip = "yes";
|
||||
for (my $excl =0; $excl < $#excludeIP; $excl++){
|
||||
if ($excludeIP[$excl] eq $1){
|
||||
@@ -2085,7 +2085,7 @@ sub parseLineNormal
|
||||
}
|
||||
if (m/ connection from/){
|
||||
my $ip;
|
||||
- if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ){
|
||||
+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ){
|
||||
$ip = $1;
|
||||
for (my $xxx =0; $xxx < $#excludeIP; $xxx++){
|
||||
if ($excludeIP[$xxx] eq $ip){$exc = "yes";}
|
||||
@@ -2253,7 +2253,7 @@ sub parseLineNormal
|
||||
}
|
||||
if ($usage =~ /g/ || $usage =~ /c/ || $usage =~ /i/ || $usage =~ /f/ || $usage =~ /u/ || $usage =~ /U/ || $verb eq "yes"){
|
||||
$exc = "no";
|
||||
- if ($_ =~ /connection from *([0-9A-fa-f\.\:]+)/i ) {
|
||||
+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ) {
|
||||
for (my $xxx = 0; $xxx < $#excludeIP; $xxx++){
|
||||
if ($1 eq $excludeIP[$xxx]){
|
||||
$exc = "yes";
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
From a59b2f4129565dbfa1b63899dd550e9c22b02923 Mon Sep 17 00:00:00 2001
|
||||
From: Mohammad Nweider <nweiderm@amazon.com>
|
||||
Date: Wed, 18 Oct 2017 13:02:15 +0000
|
||||
Subject: [PATCH] Ticket 49401 - improve valueset sorted performance on delete
|
||||
|
||||
Bug Description: valueset sorted maintains a list of syntax sorted
|
||||
references to the attributes of the entry. During addition these are
|
||||
modified and added properly, so they stay sorted.
|
||||
|
||||
However, in the past to maintain the sorted property, during a delete
|
||||
we would need to remove the vs->sorted array, and recreate it via qsort,
|
||||
|
||||
While this was an improvement from past (where we would removed
|
||||
vs->sorted during an attr delete), it still has performance implications
|
||||
on very very large datasets, IE 50,000 member groups with
|
||||
addition/deletion, large entry caches and replication.
|
||||
|
||||
Fix Description: Implement a new algorithm that is able to maintain
|
||||
existing sort data in a near linear time.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49401
|
||||
|
||||
Author: nweiderm, wibrown
|
||||
|
||||
Review by: wibrown, lkrispen, tbordaz (Thanks nweiderm!)
|
||||
|
||||
(cherry picked from commit a43a8efc7907116146b505ac40f18fac71f474b0)
|
||||
---
|
||||
ldap/servers/slapd/valueset.c | 171 +++++++++++++++++++++++++-----------------
|
||||
1 file changed, 103 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
||||
index d2c67d2fb..1c1bc150a 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -677,100 +677,136 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
int nextValue = 0;
|
||||
+ int nv = 0;
|
||||
int numValues = 0;
|
||||
+ Slapi_Value **va2 = NULL;
|
||||
+ int *sorted2 = NULL;
|
||||
|
||||
/* Loop over all the values freeing the old ones. */
|
||||
- for (i = 0; i < vs->num; i++) {
|
||||
+ for(i = 0; i < vs->num; i++)
|
||||
+ {
|
||||
/* If we have the sorted array, find the va array ref by it. */
|
||||
if (vs->sorted) {
|
||||
j = vs->sorted[i];
|
||||
} else {
|
||||
j = i;
|
||||
}
|
||||
- csnset_purge(&(vs->va[j]->v_csnset), csn);
|
||||
- if (vs->va[j]->v_csnset == NULL) {
|
||||
- slapi_value_free(&vs->va[j]);
|
||||
- vs->va[j] = NULL;
|
||||
- } else if (vs->va[j] != NULL) {
|
||||
- /* This value survived, we should count it. */
|
||||
- numValues++;
|
||||
+ if (vs->va[j]) {
|
||||
+ csnset_purge(&(vs->va[j]->v_csnset),csn);
|
||||
+ if (vs->va[j]->v_csnset == NULL) {
|
||||
+ slapi_value_free(&vs->va[j]);
|
||||
+ /* Set the removed value to NULL so we know later to skip it */
|
||||
+ vs->va[j] = NULL;
|
||||
+ if (vs->sorted) {
|
||||
+ /* Mark the value in sorted for removal */
|
||||
+ vs->sorted[i] = -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* This value survived, we should count it. */
|
||||
+ numValues++;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
- /* Now compact the value/sorted list. */
|
||||
+ /* Compact vs->va and vs->sorted only when there're
|
||||
+ * remaining values ie: numValues is greater than 0 */
|
||||
/*
|
||||
- * Because we want to preserve the sorted array, this is complicated.
|
||||
+ * Algorithm explination: We start with a pair of arrays - the attrs, and the sorted array that provides
|
||||
+ * a lookup into it:
|
||||
+ *
|
||||
+ * va: [d e a c b] sorted: [2 4 3 0 1]
|
||||
+ *
|
||||
+ * When we remove the element b, we NULL it, and we have to mark the place where it "was" as a -1 to
|
||||
+ * flag it's removal.
|
||||
+ *
|
||||
+ * va: [d e a c NULL] sorted: [2 -1 3 0 1]
|
||||
+ *
|
||||
+ * Now a second va is created with the reduced allocation,
|
||||
+ *
|
||||
+ * va2: [ X X X X ] ....
|
||||
+ *
|
||||
+ * Now we loop over sorted, skipping -1 that we find. In a new counter we create new sorted
|
||||
+ * references, and move the values compacting them in the process.
|
||||
+ * va: [d e a c NULL]
|
||||
+ * va2: [a x x x]
|
||||
+ * sorted: [_0 -1 3 0 1]
|
||||
+ *
|
||||
+ * Looping a few more times would yield:
|
||||
*
|
||||
- * We have an array of values:
|
||||
- * [ b, a, c, NULL, e, NULL, NULL, d]
|
||||
- * And an array of indicies that are sorted.
|
||||
- * [ 1, 0, 2, 7, 4, 3, 5, 6 ]
|
||||
- * Were we to iterate over the sorted array, we get refs to the values in
|
||||
- * some order.
|
||||
- * The issue is now we must *remove* from both the values *and* the sorted.
|
||||
+ * va2: [a c x x]
|
||||
+ * sorted: [_0 _1 3 0 1]
|
||||
*
|
||||
- * Previously, we just discarded this, because too hard. Now we try to keep
|
||||
- * it. The issue is that this is surprisingly hard to actually keep in
|
||||
- * sync.
|
||||
+ * va2: [a c d x]
|
||||
+ * sorted: [_0 _1 _2 0 1]
|
||||
*
|
||||
- * We can't just blindly move the values down: That breaks the sorted array
|
||||
- * and we would need to iterate over the sorted array multiple times to
|
||||
- * achieve this.
|
||||
+ * va2: [a c d e]
|
||||
+ * sorted: [_0 _1 _2 _3 1]
|
||||
+ *
|
||||
+ * Not only does this sort va, but with sorted, we have a faster lookup, and it will benefit cache
|
||||
+ * lookup.
|
||||
*
|
||||
- * It's actually going to be easier to just ditch the sorted, compact vs
|
||||
- * and then qsort the array.
|
||||
*/
|
||||
+ if (numValues > 0) {
|
||||
+ if(vs->sorted) {
|
||||
+ /* Let's allocate va2 and sorted2 */
|
||||
+ va2 = (Slapi_Value **) slapi_ch_malloc( (numValues + 1) * sizeof(Slapi_Value *));
|
||||
+ sorted2 = (int *) slapi_ch_malloc( (numValues + 1)* sizeof(int));
|
||||
+ }
|
||||
|
||||
- j = 0;
|
||||
- while (nextValue < numValues && j < vs->num) {
|
||||
- /* nextValue is what we are looking at now
|
||||
- * j tracks along the array getting next elements.
|
||||
- *
|
||||
- * [ b, a, c, NULL, e, NULL, NULL, d]
|
||||
- * ^nv ^j
|
||||
- * [ b, a, c, e, NULL, NULL, NULL, d]
|
||||
- * ^nv ^j
|
||||
- * [ b, a, c, e, NULL, NULL, NULL, d]
|
||||
- * ^nv ^j
|
||||
- * [ b, a, c, e, NULL, NULL, NULL, d]
|
||||
- * ^nv ^j
|
||||
- * [ b, a, c, e, NULL, NULL, NULL, d]
|
||||
- * ^nv ^j
|
||||
- * [ b, a, c, e, d, NULL, NULL, NULL]
|
||||
- * ^nv ^j
|
||||
- */
|
||||
- if (vs->va[nextValue] == NULL) {
|
||||
- /* Advance j till we find something */
|
||||
- while (vs->va[j] == NULL) {
|
||||
- j++;
|
||||
+ /* I is the index for the *new* va2 array */
|
||||
+ for(i=0; i<vs->num; i++) {
|
||||
+ if (vs->sorted) {
|
||||
+ /* Skip any removed values from the index */
|
||||
+ while((nv < vs->num) && (-1 == vs->sorted[nv])) {
|
||||
+ nv++;
|
||||
+ }
|
||||
+ /* We have a remaining value, add it to the va */
|
||||
+ if(nv < vs->num) {
|
||||
+ va2[i] = vs->va[vs->sorted[nv]];
|
||||
+ sorted2[i] = i;
|
||||
+ nv++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ while((nextValue < vs->num) && (NULL == vs->va[nextValue])) {
|
||||
+ nextValue++;
|
||||
+ }
|
||||
+
|
||||
+ if(nextValue < vs->num) {
|
||||
+ vs->va[i] = vs->va[nextValue];
|
||||
+ nextValue++;
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- /* We have something! */
|
||||
- vs->va[nextValue] = vs->va[j];
|
||||
- vs->va[j] = NULL;
|
||||
}
|
||||
- nextValue++;
|
||||
- }
|
||||
- /* Fix up the number of values */
|
||||
- vs->num = numValues;
|
||||
- /* Should we re-alloc values to be smaller? */
|
||||
- /* Other parts of DS are lazy. Lets clean our list */
|
||||
- for (j = vs->num; j < vs->max; j++) {
|
||||
- vs->va[j] = NULL;
|
||||
- }
|
||||
|
||||
- /* All the values were deleted, we can discard the whole array. */
|
||||
- if (vs->num == 0) {
|
||||
if (vs->sorted) {
|
||||
+ /* Finally replace the valuearray and adjust num, max */
|
||||
+ slapi_ch_free((void **)&vs->va);
|
||||
slapi_ch_free((void **)&vs->sorted);
|
||||
+ vs->va = va2;
|
||||
+ vs->sorted = sorted2;
|
||||
+ vs->num = numValues;
|
||||
+ vs->max = vs->num + 1;
|
||||
+ } else {
|
||||
+ vs->num = numValues;
|
||||
}
|
||||
- slapi_ch_free((void **)&vs->va);
|
||||
- vs->va = NULL;
|
||||
- vs->max = 0;
|
||||
- } else if (vs->sorted != NULL) {
|
||||
- /* We still have values! rebuild the sorted array */
|
||||
- valueset_array_to_sorted(a, vs);
|
||||
+
|
||||
+ for (j = vs->num; j < vs->max; j++) {
|
||||
+ vs->va[j] = NULL;
|
||||
+ if (vs->sorted) {
|
||||
+ vs->sorted[j] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ slapi_valueset_done(vs);
|
||||
}
|
||||
|
||||
+ /* We still have values but not sorted array! rebuild it */
|
||||
+ if(vs->num > VALUESET_ARRAY_SORT_THRESHOLD && vs->sorted == NULL) {
|
||||
+ vs->sorted = (int *) slapi_ch_malloc( vs->max* sizeof(int));
|
||||
+ valueset_array_to_sorted(a, vs);
|
||||
+ }
|
||||
#ifdef DEBUG
|
||||
PR_ASSERT(vs->num == 0 || (vs->num > 0 && vs->va[0] != NULL));
|
||||
size_t index = 0;
|
||||
@@ -781,7 +817,6 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
PR_ASSERT(vs->va[index] == NULL);
|
||||
}
|
||||
#endif
|
||||
-
|
||||
/* return the number of remaining values */
|
||||
return numValues;
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
From 308691e03cc6312bde3409b346df3156d34db0fe Mon Sep 17 00:00:00 2001
|
||||
From: Mohammad Nweider <nweiderm@amazon.com>
|
||||
Date: Wed, 25 Oct 2017 16:26:54 +0000
|
||||
Subject: [PATCH] Ticket 49401 - Fix compiler incompatible-pointer-types
|
||||
warnings
|
||||
|
||||
Bug Description: vs->sorted was integer pointer in older versions,
|
||||
but now it's size_t pointer, this is causing compiler warnings
|
||||
during the build
|
||||
|
||||
Fix Description: use size_t pointers instead of integer pointers for vs->sorted and sorted2
|
||||
|
||||
Review By: mreynolds
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
(cherry picked from commit 52ba2aba49935989152010aee0d40b01d7a78432)
|
||||
---
|
||||
ldap/servers/slapd/valueset.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
||||
index 1c1bc150a..dc0360738 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -680,7 +680,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
int nv = 0;
|
||||
int numValues = 0;
|
||||
Slapi_Value **va2 = NULL;
|
||||
- int *sorted2 = NULL;
|
||||
+ size_t *sorted2 = NULL;
|
||||
|
||||
/* Loop over all the values freeing the old ones. */
|
||||
for(i = 0; i < vs->num; i++)
|
||||
@@ -750,7 +750,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
if(vs->sorted) {
|
||||
/* Let's allocate va2 and sorted2 */
|
||||
va2 = (Slapi_Value **) slapi_ch_malloc( (numValues + 1) * sizeof(Slapi_Value *));
|
||||
- sorted2 = (int *) slapi_ch_malloc( (numValues + 1)* sizeof(int));
|
||||
+ sorted2 = (size_t *) slapi_ch_malloc( (numValues + 1)* sizeof(size_t));
|
||||
}
|
||||
|
||||
/* I is the index for the *new* va2 array */
|
||||
@@ -804,7 +804,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
|
||||
/* We still have values but not sorted array! rebuild it */
|
||||
if(vs->num > VALUESET_ARRAY_SORT_THRESHOLD && vs->sorted == NULL) {
|
||||
- vs->sorted = (int *) slapi_ch_malloc( vs->max* sizeof(int));
|
||||
+ vs->sorted = (size_t *) slapi_ch_malloc( vs->max* sizeof(size_t));
|
||||
valueset_array_to_sorted(a, vs);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
From dba89dd23d2d62686de192e0986eba65270a62c7 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 26 Oct 2017 10:03:39 -0400
|
||||
Subject: [PATCH] Ticket 48894 - harden valueset_array_to_sorted_quick valueset
|
||||
access
|
||||
|
||||
Description: It's possible during the sorting of a valueset to access an
|
||||
array element past the allocated size, and also go below the index 0.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48894
|
||||
|
||||
Reviewed by: nweiderm (Thanks!)
|
||||
|
||||
(cherry picked from commit 2086d052e338ddcbcf6bd3222617991641573a12)
|
||||
---
|
||||
ldap/servers/slapd/valueset.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
||||
index dc0360738..14ebc48e6 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -1019,11 +1019,11 @@ valueset_array_to_sorted_quick(const Slapi_Attr *a, Slapi_ValueSet *vs, size_t l
|
||||
while (1) {
|
||||
do {
|
||||
i++;
|
||||
- } while (valueset_value_cmp(a, vs->va[vs->sorted[i]], vs->va[pivot]) < 0);
|
||||
+ } while (i < vs->max && valueset_value_cmp(a, vs->va[vs->sorted[i]], vs->va[pivot]) < 0);
|
||||
|
||||
do {
|
||||
j--;
|
||||
- } while (valueset_value_cmp(a, vs->va[vs->sorted[j]], vs->va[pivot]) > 0);
|
||||
+ } while (valueset_value_cmp(a, vs->va[vs->sorted[j]], vs->va[pivot]) > 0 && j > 0);
|
||||
|
||||
if (i >= j) {
|
||||
break;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
From 5909e20899334816f36cac0e47105e56df52ad3c Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 30 Oct 2017 12:01:34 +1000
|
||||
Subject: [PATCH] Ticket 49424 - Resolve csiphash alignment issues
|
||||
|
||||
Bug Description: On some platforms, uint64_t is not the same size
|
||||
as a void * - as well, if the input is not aligned correctly, then
|
||||
a number of nasty crashes can result
|
||||
|
||||
Fix Description: Instead of relying on alignment to be correct,
|
||||
we should memcpy the data to inputs instead.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49424
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: lslebodn, cgrzemba, vashirov, mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit 751446440f5269a246e6e652a64e63aa5933734a)
|
||||
---
|
||||
src/libsds/external/csiphash/csiphash.c | 52 +++++++++++++++++++--------------
|
||||
src/libsds/test/test_sds_csiphash.c | 43 +++++++++++++++++++++------
|
||||
2 files changed, 64 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/libsds/external/csiphash/csiphash.c b/src/libsds/external/csiphash/csiphash.c
|
||||
index 0089c82f7..2351db6cf 100644
|
||||
--- a/src/libsds/external/csiphash/csiphash.c
|
||||
+++ b/src/libsds/external/csiphash/csiphash.c
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h> /* for size_t */
|
||||
|
||||
+#include <stdlib.h> /* calloc,free */
|
||||
+#include <string.h> /* memcpy */
|
||||
+
|
||||
#include <config.h>
|
||||
|
||||
#if defined(HAVE_SYS_ENDIAN_H)
|
||||
@@ -75,11 +78,24 @@
|
||||
uint64_t
|
||||
sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
||||
{
|
||||
- const uint64_t *_key = (uint64_t *)key;
|
||||
+ uint64_t _key[2] = {0};
|
||||
+ memcpy(_key, key, 16);
|
||||
uint64_t k0 = _le64toh(_key[0]);
|
||||
uint64_t k1 = _le64toh(_key[1]);
|
||||
uint64_t b = (uint64_t)src_sz << 56;
|
||||
- const uint64_t *in = (uint64_t *)src;
|
||||
+
|
||||
+ size_t input_sz = (src_sz / sizeof(uint64_t)) + 1;
|
||||
+
|
||||
+ /* Account for non-uint64_t alligned input */
|
||||
+ /* Could make this stack allocation */
|
||||
+ uint64_t *in = calloc(1, input_sz * sizeof(uint64_t));
|
||||
+ /*
|
||||
+ * Because all crypto code sucks, they modify *in
|
||||
+ * during operation, so we stash a copy of the ptr here.
|
||||
+ * alternately, we could use stack allocated array, but gcc
|
||||
+ * will complain about the vla being unbounded.
|
||||
+ */
|
||||
+ uint64_t *in_ptr = memcpy(in, src, src_sz);
|
||||
|
||||
uint64_t v0 = k0 ^ 0x736f6d6570736575ULL;
|
||||
uint64_t v1 = k1 ^ 0x646f72616e646f6dULL;
|
||||
@@ -96,27 +112,15 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
||||
v0 ^= mi;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Because we allocate in as size + 1, we can over-read 0
|
||||
+ * for this buffer to be padded correctly. in here is a pointer to the
|
||||
+ * excess data because the while loop above increments the in pointer
|
||||
+ * to point to the excess once src_sz drops < 8.
|
||||
+ */
|
||||
uint64_t t = 0;
|
||||
- uint8_t *pt = (uint8_t *)&t;
|
||||
- uint8_t *m = (uint8_t *)in;
|
||||
-
|
||||
- switch (src_sz) {
|
||||
- case 7:
|
||||
- pt[6] = m[6]; /* FALLTHRU */
|
||||
- case 6:
|
||||
- pt[5] = m[5]; /* FALLTHRU */
|
||||
- case 5:
|
||||
- pt[4] = m[4]; /* FALLTHRU */
|
||||
- case 4:
|
||||
- *((uint32_t *)&pt[0]) = *((uint32_t *)&m[0]);
|
||||
- break;
|
||||
- case 3:
|
||||
- pt[2] = m[2]; /* FALLTHRU */
|
||||
- case 2:
|
||||
- pt[1] = m[1]; /* FALLTHRU */
|
||||
- case 1:
|
||||
- pt[0] = m[0]; /* FALLTHRU */
|
||||
- }
|
||||
+ memcpy(&t, in, sizeof(uint64_t));
|
||||
+
|
||||
b |= _le64toh(t);
|
||||
|
||||
v3 ^= b;
|
||||
@@ -126,5 +130,9 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16])
|
||||
v2 ^= 0xff;
|
||||
// dround
|
||||
dROUND(v0, v1, v2, v3);
|
||||
+
|
||||
+ free(in_ptr);
|
||||
+
|
||||
return (v0 ^ v1) ^ (v2 ^ v3);
|
||||
}
|
||||
+
|
||||
diff --git a/src/libsds/test/test_sds_csiphash.c b/src/libsds/test/test_sds_csiphash.c
|
||||
index cdb6b7f46..cc9a6b2b5 100644
|
||||
--- a/src/libsds/test/test_sds_csiphash.c
|
||||
+++ b/src/libsds/test/test_sds_csiphash.c
|
||||
@@ -25,23 +25,48 @@
|
||||
static void
|
||||
test_siphash(void **state __attribute__((unused)))
|
||||
{
|
||||
-
|
||||
- //
|
||||
uint64_t value = 0;
|
||||
uint64_t hashout = 0;
|
||||
char key[16] = {0};
|
||||
|
||||
- uint64_t test_a = 15794382300316794652U;
|
||||
- uint64_t test_b = 13042610424265326907U;
|
||||
+ uint64_t test_simple = 15794382300316794652U;
|
||||
|
||||
- // Initial simple test
|
||||
+ /* Initial simple test */
|
||||
value = htole64(5);
|
||||
hashout = sds_siphash13(&value, sizeof(uint64_t), key);
|
||||
- assert_true(hashout == test_a);
|
||||
+ assert_int_equal(hashout, test_simple);
|
||||
+
|
||||
+ /* Test a range of input sizes to check endianness behaviour */
|
||||
+
|
||||
+ hashout = sds_siphash13("a", 1, key);
|
||||
+ assert_int_equal(hashout, 0x407448d2b89b1813U);
|
||||
+
|
||||
+ hashout = sds_siphash13("aa", 2, key);
|
||||
+ assert_int_equal(hashout, 0x7910e0436ed8d1deU);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaa", 3, key);
|
||||
+ assert_int_equal(hashout, 0xf752893a6c769652U);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaa", 4, key);
|
||||
+ assert_int_equal(hashout, 0x8b02350718d87164U);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaaa", 5, key);
|
||||
+ assert_int_equal(hashout, 0x92a991474c7eef2U);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaaaa", 6, key);
|
||||
+ assert_int_equal(hashout, 0xf0ab815a640277ccU);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaaaaa", 7, key);
|
||||
+ assert_int_equal(hashout, 0x33f3c6d7dbc82c0dU);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaaaaaa", 8, key);
|
||||
+ assert_int_equal(hashout, 0xc501b12e18428c92U);
|
||||
+
|
||||
+ hashout = sds_siphash13("aaaaaaaabbbb", 12, key);
|
||||
+ assert_int_equal(hashout, 0xcddca673069ade64U);
|
||||
|
||||
- char *test = "abc";
|
||||
- hashout = sds_siphash13(test, 4, key);
|
||||
- assert_true(hashout == test_b);
|
||||
+ hashout = sds_siphash13("aaaaaaaabbbbbbbb", 16, key);
|
||||
+ assert_int_equal(hashout, 0xdc54f0bfc0e1deb0U);
|
||||
}
|
||||
|
||||
int
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
From dcf75750dff23e848cde2ae63a0778b123de6dd7 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Thu, 2 Nov 2017 13:32:41 +1000
|
||||
Subject: [PATCH] Ticket 49436 - double free in COS in some conditions
|
||||
|
||||
Bug Description: virtualattrs and COS have some serious memory
|
||||
ownership issues. What was happening is that COS with multiple
|
||||
attributes using the same sp_handle would cause a structure
|
||||
to be registered twice. During shutdown we would then trigger
|
||||
a double free in the process.
|
||||
|
||||
Fix Description: Change the behaviour of sp_handles to use a
|
||||
handle *per* attribute we register to guarantee the assocation
|
||||
between them.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49436
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds, vashirov (Thanks!)
|
||||
|
||||
(cherry pick from commit ee4428a3f5d2d8e37a7107c7dce9d622fc17d41c)
|
||||
---
|
||||
dirsrvtests/tests/suites/cos/indirect_cos_test.py | 43 +++++++----------------
|
||||
ldap/servers/plugins/cos/cos_cache.c | 32 +++++++++--------
|
||||
ldap/servers/plugins/roles/roles_cache.c | 8 ++---
|
||||
ldap/servers/slapd/vattr.c | 28 +++++++++------
|
||||
4 files changed, 51 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
index 1aac6b8ed..452edcdf8 100644
|
||||
--- a/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
||||
@@ -7,6 +7,7 @@ import subprocess
|
||||
|
||||
from lib389 import Entry
|
||||
from lib389.idm.user import UserAccounts
|
||||
+from lib389.idm.domain import Domain
|
||||
from lib389.topologies import topology_st as topo
|
||||
from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE,
|
||||
SERVERID_STANDALONE, PORT_STANDALONE)
|
||||
@@ -48,14 +49,8 @@ def check_user(inst):
|
||||
def setup_subtree_policy(topo):
|
||||
"""Set up subtree password policy
|
||||
"""
|
||||
- try:
|
||||
- topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE,
|
||||
- 'nsslapd-pwpolicy-local',
|
||||
- 'on')])
|
||||
- except ldap.LDAPError as e:
|
||||
- log.error('Failed to set fine-grained policy: error {}'.format(
|
||||
- e.message['desc']))
|
||||
- raise e
|
||||
+
|
||||
+ topo.standalone.config.set('nsslapd-pwpolicy-local', 'on')
|
||||
|
||||
log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
|
||||
try:
|
||||
@@ -68,15 +63,9 @@ def setup_subtree_policy(topo):
|
||||
OU_PEOPLE, e.message['desc']))
|
||||
raise e
|
||||
|
||||
- log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
|
||||
- try:
|
||||
- topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE,
|
||||
- 'pwdpolicysubentry',
|
||||
- PW_POLICY_CONT_PEOPLE2)])
|
||||
- except ldap.LDAPError as e:
|
||||
- log.error('Failed to pwdpolicysubentry pw policy '
|
||||
- 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc']))
|
||||
- raise e
|
||||
+ domain = Domain(topo.standalone, DEFAULT_SUFFIX)
|
||||
+ domain.replace('pwdpolicysubentry', PW_POLICY_CONT_PEOPLE2)
|
||||
+
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
@@ -116,12 +105,9 @@ def setup(topo, request):
|
||||
"""
|
||||
log.info('Add custom schema...')
|
||||
try:
|
||||
- ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " +
|
||||
- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
- ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " +
|
||||
- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
- OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " +
|
||||
- "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )")
|
||||
+ ATTR_1 = (b"( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ ATTR_2 = (b"( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
||||
+ OC = (b"( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY ( x-department $ x-en-ou ) X-ORIGIN 'user defined' )")
|
||||
topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1),
|
||||
(ldap.MOD_ADD, 'attributeTypes', ATTR_2),
|
||||
(ldap.MOD_ADD, 'objectClasses', OC)])
|
||||
@@ -142,14 +128,9 @@ def setup(topo, request):
|
||||
'homeDirectory': '/home/test_user',
|
||||
'seeAlso': 'cn=cosTemplate,dc=example,dc=com'
|
||||
}
|
||||
- users.create(properties=user_properties)
|
||||
- try:
|
||||
- topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD,
|
||||
- 'objectclass',
|
||||
- 'xPerson')])
|
||||
- except ldap.LDAPError as e:
|
||||
- log.fatal('Failed to add objectclass to user')
|
||||
- raise e
|
||||
+ user = users.create(properties=user_properties)
|
||||
+
|
||||
+ user.add('objectClass', 'xPerson')
|
||||
|
||||
# Setup COS
|
||||
log.info("Setup indirect COS...")
|
||||
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index 9ae15db15..662dace35 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -109,9 +109,6 @@ void *cos_get_plugin_identity(void);
|
||||
#define COSTYPE_INDIRECT 3
|
||||
#define COS_DEF_ERROR_NO_TEMPLATES -2
|
||||
|
||||
-/* the global plugin handle */
|
||||
-static volatile vattr_sp_handle *vattr_handle = NULL;
|
||||
-
|
||||
/* both variables are protected by change_lock */
|
||||
static int cos_cache_notify_flag = 0;
|
||||
static PRBool cos_cache_at_work = PR_FALSE;
|
||||
@@ -323,16 +320,6 @@ cos_cache_init(void)
|
||||
views_api = 0;
|
||||
}
|
||||
|
||||
- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
- cos_cache_vattr_get,
|
||||
- cos_cache_vattr_compare,
|
||||
- cos_cache_vattr_types) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM,
|
||||
- "cos_cache_init - Cannot register as service provider\n");
|
||||
- ret = -1;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (PR_CreateThread(PR_USER_THREAD,
|
||||
cos_cache_wait_on_change,
|
||||
NULL,
|
||||
@@ -860,8 +847,23 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data)
|
||||
dnVals[valIndex]->bv_val);
|
||||
}
|
||||
|
||||
- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle,
|
||||
- dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
+ /*
|
||||
+ * Each SP_handle is associated to one and only one vattr.
|
||||
+ * We could consider making this a single function rather
|
||||
+ * than the double-call.
|
||||
+ */
|
||||
+
|
||||
+ vattr_sp_handle *vattr_handle = NULL;
|
||||
+
|
||||
+ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
+ cos_cache_vattr_get,
|
||||
+ cos_cache_vattr_compare,
|
||||
+ cos_cache_vattr_types) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val);
|
||||
+ } else {
|
||||
+ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
+ }
|
||||
+
|
||||
} /* if(attrType is cosAttribute) */
|
||||
|
||||
/*
|
||||
diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c
|
||||
index 59f5a6081..1e5865af8 100644
|
||||
--- a/ldap/servers/plugins/roles/roles_cache.c
|
||||
+++ b/ldap/servers/plugins/roles/roles_cache.c
|
||||
@@ -47,9 +47,6 @@ static char *allUserAttributes[] = {
|
||||
/* views scoping */
|
||||
static void **views_api;
|
||||
|
||||
-/* Service provider handler */
|
||||
-static vattr_sp_handle *vattr_handle = NULL;
|
||||
-
|
||||
/* List of nested roles */
|
||||
typedef struct _role_object_nested
|
||||
{
|
||||
@@ -224,6 +221,10 @@ roles_cache_init()
|
||||
so that we update the corresponding cache */
|
||||
slapi_register_backend_state_change(NULL, roles_cache_trigger_update_suffix);
|
||||
|
||||
+ /* Service provider handler - only used once! and freed by vattr! */
|
||||
+ vattr_sp_handle *vattr_handle = NULL;
|
||||
+
|
||||
+
|
||||
if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
roles_sp_get_value,
|
||||
roles_sp_compare_value,
|
||||
@@ -622,7 +623,6 @@ roles_cache_stop()
|
||||
current_role = next_role;
|
||||
}
|
||||
slapi_rwlock_unlock(global_lock);
|
||||
- slapi_ch_free((void **)&vattr_handle);
|
||||
roles_list = NULL;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<-- roles_cache_stop\n");
|
||||
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||||
index 82deb41fe..432946c79 100644
|
||||
--- a/ldap/servers/slapd/vattr.c
|
||||
+++ b/ldap/servers/slapd/vattr.c
|
||||
@@ -1864,7 +1864,12 @@ vattr_map_create(void)
|
||||
void
|
||||
vattr_map_entry_free(vattr_map_entry *vae)
|
||||
{
|
||||
- slapi_ch_free((void **)&(vae->sp_list));
|
||||
+ vattr_sp_handle *list_entry = vae->sp_list;
|
||||
+ while (list_entry != NULL) {
|
||||
+ vattr_sp_handle *next_entry = list_entry->next;
|
||||
+ slapi_ch_free((void **)&list_entry);
|
||||
+ list_entry = next_entry;
|
||||
+ }
|
||||
slapi_ch_free_string(&(vae->type_name));
|
||||
slapi_ch_free((void **)&vae);
|
||||
}
|
||||
@@ -2143,16 +2148,9 @@ slapi_vattr_schema_check_type(Slapi_Entry *e, char *type)
|
||||
vattr_map_entry *
|
||||
vattr_map_entry_new(char *type_name, vattr_sp_handle *sph, void *hint)
|
||||
{
|
||||
- vattr_map_entry *result = NULL;
|
||||
- vattr_sp_handle *sp_copy = NULL;
|
||||
-
|
||||
- sp_copy = (vattr_sp_handle *)slapi_ch_calloc(1, sizeof(vattr_sp_handle));
|
||||
- sp_copy->sp = sph->sp;
|
||||
- sp_copy->hint = hint;
|
||||
-
|
||||
- result = (vattr_map_entry *)slapi_ch_calloc(1, sizeof(vattr_map_entry));
|
||||
+ vattr_map_entry *result = (vattr_map_entry *)slapi_ch_calloc(1, sizeof(vattr_map_entry));
|
||||
result->type_name = slapi_ch_strdup(type_name);
|
||||
- result->sp_list = sp_copy;
|
||||
+ result->sp_list = sph;
|
||||
|
||||
/* go get schema */
|
||||
result->objectclasses = vattr_map_entry_build_schema(type_name);
|
||||
@@ -2273,6 +2271,16 @@ we'd need to hold a lock on the read path, which we don't want to do.
|
||||
So any SP which relinquishes its need to handle a type needs to continue
|
||||
to handle the calls on it, but return nothing */
|
||||
/* DBDB need to sort out memory ownership here, it's not quite right */
|
||||
+/*
|
||||
+ * This function was inconsistent. We would allocated and "kind of",
|
||||
+ * copy the sp_handle here for the vattr_map_entry_new path. But we
|
||||
+ * would "take ownership" for the existing entry and the list addition
|
||||
+ * path. Instead now, EVERY sp_handle we take, we take ownership of
|
||||
+ * and the CALLER must allocate a new one each time.
|
||||
+ *
|
||||
+ * Better idea, is that regattr should just take the fn pointers
|
||||
+ * and callers never *see* the sp_handle structure at all.
|
||||
+ */
|
||||
|
||||
int
|
||||
vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint)
|
||||
--
|
||||
2.13.6
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,169 +0,0 @@
|
|||
From 403c5b61efb5aca3cbea31170d13dfba190ef355 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 2 Nov 2017 12:55:11 -0400
|
||||
Subject: [PATCH] Ticket 49439 - cleanallruv is not logging information
|
||||
|
||||
Bug Description: During the logging refector effro from ticket 48978
|
||||
a mistake was made and cleanruv_log() was using
|
||||
LOG_NOTICE (which is not a true log level), it was
|
||||
supposed to be SLAPI_LOG_NOTICE.
|
||||
|
||||
We also use DEBUG defines to contorl the logging for
|
||||
debug builds
|
||||
|
||||
Fix Description: Remove the LDAP_DEBUG defines in cleanruv_log, and set
|
||||
the correct logging severity level.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49439
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit e1f866a5e3ccce8e061e361c0e3dd11175a8acf2)
|
||||
---
|
||||
.../plugins/replication/repl5_replica_config.c | 30 ++++++++++------------
|
||||
1 file changed, 14 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 9c3c75458..9c8d6adbb 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -1783,7 +1783,7 @@ replica_cleanallruv_thread(void *arg)
|
||||
/*
|
||||
* need to sleep between passes
|
||||
*/
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Not all replicas have received the "
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas have received the "
|
||||
"cleanallruv extended op, retrying in %d seconds",
|
||||
interval);
|
||||
if (!slapi_is_shutting_down()) {
|
||||
@@ -1825,7 +1825,7 @@ replica_cleanallruv_thread(void *arg)
|
||||
found_dirty_rid = 0;
|
||||
} else {
|
||||
found_dirty_rid = 1;
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Replica is not cleaned yet (%s)",
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica is not cleaned yet (%s)",
|
||||
agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
@@ -1843,7 +1843,7 @@ replica_cleanallruv_thread(void *arg)
|
||||
* Need to sleep between passes unless we are shutting down
|
||||
*/
|
||||
if (!slapi_is_shutting_down()) {
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Replicas have not been cleaned yet, "
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replicas have not been cleaned yet, "
|
||||
"retrying in %d seconds",
|
||||
interval);
|
||||
PR_Lock(notify_lock);
|
||||
@@ -1883,10 +1883,10 @@ done:
|
||||
* Shutdown or abort
|
||||
*/
|
||||
if (!is_task_aborted(data->rid) || slapi_is_shutting_down()) {
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Server shutting down. Process will resume at server startup");
|
||||
} else {
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Task aborted for rid(%d).", data->rid);
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Task aborted for rid(%d).", data->rid);
|
||||
delete_cleaned_rid_config(data);
|
||||
remove_cleaned_rid(data->rid);
|
||||
}
|
||||
@@ -2053,7 +2053,7 @@ check_replicas_are_done_cleaning(cleanruv_data *data)
|
||||
break;
|
||||
}
|
||||
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Not all replicas finished cleaning, retrying in %d seconds",
|
||||
interval);
|
||||
if (!slapi_is_shutting_down()) {
|
||||
@@ -2163,7 +2163,7 @@ check_replicas_are_done_aborting(cleanruv_data *data)
|
||||
if (not_all_aborted == 0) {
|
||||
break;
|
||||
}
|
||||
- cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Not all replicas finished aborting, retrying in %d seconds", interval);
|
||||
if (!slapi_is_shutting_down()) {
|
||||
PR_Lock(notify_lock);
|
||||
@@ -2210,7 +2210,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn)
|
||||
not_all_caughtup = 0;
|
||||
} else {
|
||||
not_all_caughtup = 1;
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Replica not caught up (%s)", agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
@@ -2220,7 +2220,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn)
|
||||
if (not_all_caughtup == 0 || is_task_aborted(data->rid)) {
|
||||
break;
|
||||
}
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Not all replicas caught up, retrying in %d seconds", interval);
|
||||
if (!slapi_is_shutting_down()) {
|
||||
PR_Lock(notify_lock);
|
||||
@@ -2270,7 +2270,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
|
||||
not_all_alive = 0;
|
||||
} else {
|
||||
not_all_alive = 1;
|
||||
- cleanruv_log(task, rid, CLEANALLRUV_ID, LOG_NOTICE, "Replica not online (%s)",
|
||||
+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica not online (%s)",
|
||||
agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
@@ -2280,7 +2280,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
|
||||
if (not_all_alive == 0 || is_task_aborted(rid)) {
|
||||
break;
|
||||
}
|
||||
- cleanruv_log(task, rid, CLEANALLRUV_ID, LOG_NOTICE, "Not all replicas online, retrying in %d seconds...",
|
||||
+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas online, retrying in %d seconds...",
|
||||
interval);
|
||||
|
||||
if (!slapi_is_shutting_down()) {
|
||||
@@ -3063,7 +3063,7 @@ replica_abort_task_thread(void *arg)
|
||||
* Need to sleep between passes. unless we are shutting down
|
||||
*/
|
||||
if (!slapi_is_shutting_down()) {
|
||||
- cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, LOG_NOTICE, "Retrying in %d seconds", interval);
|
||||
+ cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Retrying in %d seconds", interval);
|
||||
PR_Lock(notify_lock);
|
||||
PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
|
||||
PR_Unlock(notify_lock);
|
||||
@@ -3184,7 +3184,7 @@ replica_cleanallruv_send_extop(Repl_Agmt *ra, cleanruv_data *clean_data, int che
|
||||
/* extop was accepted */
|
||||
rc = 0;
|
||||
} else {
|
||||
- cleanruv_log(clean_data->task, clean_data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(clean_data->task, clean_data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Replica %s does not support the CLEANALLRUV task. "
|
||||
"Sending replica CLEANRUV task...",
|
||||
slapi_sdn_get_dn(agmt_get_dn_byref(ra)));
|
||||
@@ -3352,7 +3352,7 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *basedn, char *rid_text,
|
||||
csn_init_by_string(repl_max, remote_maxcsn);
|
||||
if (csn_compare(repl_max, max) < 0) {
|
||||
/* we are not caught up yet, free, and return */
|
||||
- cleanruv_log(task, atoi(rid_text), CLEANALLRUV_ID, LOG_NOTICE,
|
||||
+ cleanruv_log(task, atoi(rid_text), CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
"Replica maxcsn (%s) is not caught up with deleted replica's maxcsn(%s)",
|
||||
remote_maxcsn, maxcsn);
|
||||
rc = -1;
|
||||
@@ -3525,7 +3525,6 @@ stop_ruv_cleaning()
|
||||
void
|
||||
cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...)
|
||||
{
|
||||
-#ifdef LDAP_DEBUG
|
||||
va_list ap1;
|
||||
va_list ap2;
|
||||
va_list ap3;
|
||||
@@ -3550,7 +3549,6 @@ cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fm
|
||||
va_end(ap2);
|
||||
va_end(ap3);
|
||||
va_end(ap4);
|
||||
-#endif
|
||||
}
|
||||
|
||||
char *
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 3d045a240bb32b66e15401bf89eff5b980420b24 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 3 Nov 2017 12:18:26 -0400
|
||||
Subject: [PATCH] Ticket 48393 - fix copy and paste error
|
||||
|
||||
Description: Copy and paste error when validating repl agmt
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48393
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
|
||||
(cherry picked from commit 431647039c5e6d860d8866542050d456f69bb600)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_agmt.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
|
||||
index 78fb91ae6..ee396c8ef 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_agmt.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
|
||||
@@ -339,7 +339,7 @@ agmt_new_from_entry(Slapi_Entry *e)
|
||||
ra->flowControlWindow = DEFAULT_FLOWCONTROL_WINDOW;
|
||||
if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlWindow))){
|
||||
int64_t flow;
|
||||
- if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) {
|
||||
+ if (repl_config_valid_num(type_nsds5ReplicaFlowControlWindow, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) {
|
||||
goto loser;
|
||||
}
|
||||
slapi_ch_free_string(&val);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From 2b5b09a7a871d626bb45888f948126732d0893f3 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 4 Oct 2017 12:55:30 -0400
|
||||
Subject: [PATCH] Ticket 49038 - remove legacy replication - change cleanup
|
||||
script precedence
|
||||
|
||||
Description: Bump the cleanup scripts precendance so it happens after the
|
||||
main plugin upgrade scripts are called.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49038
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 1fe2c761103c36090ab67df0271dfdb3012037fb)
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
...{50removeLegacyReplication.ldif => 60removeLegacyReplication.ldif} | 0
|
||||
rpm/389-ds-base.spec.in | 4 ++--
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
rename ldap/admin/src/scripts/{50removeLegacyReplication.ldif => 60removeLegacyReplication.ldif} (100%)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 09a6bc296..8834a7819 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -942,7 +942,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
|
||||
ldap/admin/src/scripts/50telexnumbersyntaxplugin.ldif \
|
||||
ldap/admin/src/scripts/50guidesyntaxplugin.ldif \
|
||||
ldap/admin/src/scripts/50targetuniqueid.ldif \
|
||||
- ldap/admin/src/scripts/50removeLegacyReplication.ldif \
|
||||
+ ldap/admin/src/scripts/60removeLegacyReplication.ldif \
|
||||
ldap/admin/src/scripts/50linkedattrsplugin.ldif \
|
||||
ldap/admin/src/scripts/50usnplugin.ldif \
|
||||
ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif \
|
||||
diff --git a/ldap/admin/src/scripts/50removeLegacyReplication.ldif b/ldap/admin/src/scripts/60removeLegacyReplication.ldif
|
||||
similarity index 100%
|
||||
rename from ldap/admin/src/scripts/50removeLegacyReplication.ldif
|
||||
rename to ldap/admin/src/scripts/60removeLegacyReplication.ldif
|
||||
diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in
|
||||
index 1e5c2cfd3..30a1d7d9a 100644
|
||||
--- a/rpm/389-ds-base.spec.in
|
||||
+++ b/rpm/389-ds-base.spec.in
|
||||
@@ -395,9 +395,9 @@ echo remove pid files . . . >> $output 2>&1 || :
|
||||
echo upgrading instances . . . >> $output 2>&1 || :
|
||||
DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"`
|
||||
if [ -n "$DEBUGPOSTSETUPOPT" ] ; then
|
||||
- %{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
+ %{_sbindir}/setup-ds.pl -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
else
|
||||
- %{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
+ %{_sbindir}/setup-ds.pl -u -s General.UpdateMode=offline >> $output 2>&1 || :
|
||||
fi
|
||||
|
||||
# restart instances that require it
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
From b1dfe53aaf7cb0260286423b9abf7d71f8edd421 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 15 Nov 2017 13:27:58 -0500
|
||||
Subject: [PATCH] Ticket 49454 - SSL Client Authentication breaks in FIPS mode
|
||||
|
||||
Bug Description: Replication using SSL Client Auth breaks when FIPS
|
||||
is enabled. This is because FIPS mode changes the
|
||||
internal certificate token name.
|
||||
|
||||
Fix Description: If FIPS is enabled grab the token name from the internal
|
||||
slot instead of using the default hardcoded internal
|
||||
token name.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49454
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 6e794a8eff213d49c933f781006e234984160db2)
|
||||
---
|
||||
ldap/servers/slapd/proto-slap.h | 1 +
|
||||
ldap/servers/slapd/security_wrappers.c | 6 ++++++
|
||||
ldap/servers/slapd/ssl.c | 24 +++++++++++++++++-------
|
||||
3 files changed, 24 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index 4a30def8b..3b7ab53b2 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -1130,6 +1130,7 @@ PRBool slapd_pk11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
|
||||
PK11SymKey *slapd_pk11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags, PRBool isPerm);
|
||||
PK11SymKey *slapd_pk11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx);
|
||||
CK_MECHANISM_TYPE slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECItem *pwitem);
|
||||
+char *slapd_PK11_GetTokenName(PK11SlotInfo *slot);
|
||||
|
||||
/*
|
||||
* start_tls_extop.c
|
||||
diff --git a/ldap/servers/slapd/security_wrappers.c b/ldap/servers/slapd/security_wrappers.c
|
||||
index bec28d2f3..41fe03608 100644
|
||||
--- a/ldap/servers/slapd/security_wrappers.c
|
||||
+++ b/ldap/servers/slapd/security_wrappers.c
|
||||
@@ -401,3 +401,9 @@ slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECIte
|
||||
{
|
||||
return PK11_GetPBECryptoMechanism(algid, params, pwitem);
|
||||
}
|
||||
+
|
||||
+char *
|
||||
+slapd_PK11_GetTokenName(PK11SlotInfo *slot)
|
||||
+{
|
||||
+ return PK11_GetTokenName(slot);
|
||||
+}
|
||||
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
|
||||
index efe32d5d0..52ac7ea9f 100644
|
||||
--- a/ldap/servers/slapd/ssl.c
|
||||
+++ b/ldap/servers/slapd/ssl.c
|
||||
@@ -2365,13 +2365,23 @@ slapd_SSL_client_auth(LDAP *ld)
|
||||
ssltoken = slapi_entry_attr_get_charptr(entry, "nsssltoken");
|
||||
if (ssltoken && personality) {
|
||||
if (!PL_strcasecmp(ssltoken, "internal") ||
|
||||
- !PL_strcasecmp(ssltoken, "internal (software)")) {
|
||||
-
|
||||
- /* Translate config internal name to more
|
||||
- * readable form. Certificate name is just
|
||||
- * the personality for internal tokens.
|
||||
- */
|
||||
- token = slapi_ch_strdup(internalTokenName);
|
||||
+ !PL_strcasecmp(ssltoken, "internal (software)"))
|
||||
+ {
|
||||
+ if ( slapd_pk11_isFIPS() ) {
|
||||
+ /*
|
||||
+ * FIPS mode changes the internal token name, so we need to
|
||||
+ * grab the new token name from the internal slot.
|
||||
+ */
|
||||
+ PK11SlotInfo *slot = slapd_pk11_getInternalSlot();
|
||||
+ token = slapi_ch_strdup(slapd_PK11_GetTokenName(slot));
|
||||
+ PK11_FreeSlot(slot);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Translate config internal name to more readable form.
|
||||
+ * Certificate name is just the personality for internal tokens.
|
||||
+ */
|
||||
+ token = slapi_ch_strdup(internalTokenName);
|
||||
+ }
|
||||
#if defined(USE_OPENLDAP)
|
||||
/* openldap needs tokenname:certnick */
|
||||
PR_snprintf(cert_name, sizeof(cert_name), "%s:%s", token, personality);
|
||||
--
|
||||
2.13.6
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,84 +0,0 @@
|
|||
From 11cea14acfc11d0328013b61a3e1396e97dfe577 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Tue, 14 Nov 2017 16:29:03 +0100
|
||||
Subject: [PATCH] Ticket 49410 - opened connection can remain no longer poll,
|
||||
like hanging
|
||||
|
||||
Bug Description:
|
||||
Some opened connection are no longer poll.
|
||||
Those connections has 'gettingber' toggle set although there is
|
||||
no more worker thread reading it.
|
||||
The reason they have gettingber set is that the last
|
||||
operation had 'persistent search' flag. With such flag
|
||||
gettingber is not reset.
|
||||
persistent flag is set even when no persistent search/sync_repl
|
||||
was received on the connection.
|
||||
The problem is that the flag is tested on the wrong operation.
|
||||
The tested operation can be
|
||||
- the first operation when the connection entered in turbo mode
|
||||
- the previous operation if several ops PDUs were read on the network
|
||||
- accessing random memory
|
||||
|
||||
In theory testing the flag can lead to sigsev even
|
||||
if it never crash
|
||||
|
||||
Fix Description:
|
||||
The fix is to use the operation that is in the pblock
|
||||
In such case pb_op is no longer used, so we can get rid of it.
|
||||
In addition make pb_conn a local variable where it is used
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49410
|
||||
|
||||
Reviewed by: Ludwig Krispenz, Mark Reynolds
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 24a7a1c05..3f19b9765 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -1498,8 +1498,6 @@ connection_threadmain()
|
||||
int maxthreads = 0;
|
||||
int enable_nunc_stans = 0;
|
||||
long bypasspollcnt = 0;
|
||||
- Connection *pb_conn = NULL;
|
||||
- Operation *pb_op = NULL;
|
||||
|
||||
enable_nunc_stans = config_get_enable_nunc_stans();
|
||||
#if defined(hpux)
|
||||
@@ -1520,6 +1518,8 @@ connection_threadmain()
|
||||
}
|
||||
|
||||
if (!thread_turbo_flag && !more_data) {
|
||||
+ Connection *pb_conn = NULL;
|
||||
+
|
||||
/* If more data is left from the previous connection_read_operation,
|
||||
we should finish the op now. Client might be thinking it's
|
||||
done sending the request and wait for the response forever.
|
||||
@@ -1530,7 +1530,6 @@ connection_threadmain()
|
||||
* Connection wait for new work provides the conn and op for us.
|
||||
*/
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
|
||||
switch (ret) {
|
||||
case CONN_NOWORK:
|
||||
@@ -1786,7 +1785,7 @@ connection_threadmain()
|
||||
/* total number of ops for the server */
|
||||
slapi_counter_increment(ops_completed);
|
||||
/* If this op isn't a persistent search, remove it */
|
||||
- if (pb_op->o_flags & OP_FLAG_PS) {
|
||||
+ if (op->o_flags & OP_FLAG_PS) {
|
||||
PR_EnterMonitor(conn->c_mutex);
|
||||
connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */
|
||||
PR_ExitMonitor(conn->c_mutex);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 5f38be985bc98969b0fdaa6ece8f84b11bdddc2f Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Thu, 9 Nov 2017 10:20:44 +0100
|
||||
Subject: [PATCH] Ticket 49443 - scope one searches in 1.3.7 give incorrect
|
||||
results
|
||||
|
||||
Bug: if a onelevel search is done for an unidexed attribute, the filter test is skipped
|
||||
and all children of the search base are returned
|
||||
|
||||
Fix: enforce filter test if allids
|
||||
|
||||
Reviewed by: Mark, thanks
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/idl_set.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
index ba39ff03f..b68e7ab76 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
@@ -349,6 +349,11 @@ idl_set_intersect(IDListSet *idl_set, backend *be)
|
||||
{
|
||||
IDList *result_list = NULL;
|
||||
|
||||
+ if (idl_set->allids) {
|
||||
+ /* if any component was allids we have to apply the filtertest */
|
||||
+ slapi_be_set_flag(be, SLAPI_BE_FLAG_DONT_BYPASS_FILTERTEST);
|
||||
+ }
|
||||
+
|
||||
if (idl_set->allids != 0 && idl_set->count == 0) {
|
||||
/*
|
||||
* We only have allids, so must be allids.
|
||||
--
|
||||
2.13.6
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,43 +0,0 @@
|
|||
From 2c868707b3ae1a4255ea33610b177f8a98f4a3f3 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 7 Nov 2017 17:09:18 +1000
|
||||
Subject: [PATCH] Ticket 49441 - Import crashes - oneline fix
|
||||
|
||||
Bug Description: index.c fails to compile.
|
||||
|
||||
Fix Description: Excess braces due to copy paste issue.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49441
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: oneline rule
|
||||
|
||||
(cherry picked from commit be4d7e5a82c1616317fa52968d2814e3f922254c)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/index.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
|
||||
index a565db87b..587f4d991 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/index.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/index.c
|
||||
@@ -1778,7 +1778,6 @@ addordel_values(
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
key.ulen = tmpbuflen;
|
||||
if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) {
|
||||
- {
|
||||
char encbuf[BUFSIZ];
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "addordel_values", "%s_value(\"%s\")\n",
|
||||
@@ -1943,7 +1942,6 @@ addordel_values_sv(
|
||||
key.ulen = tmpbuflen;
|
||||
|
||||
if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) {
|
||||
- {
|
||||
char encbuf[BUFSIZ];
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "addordel_values_sv", "%s_value(\"%s\")\n",
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
From 40811ab7571ddf0a6905b3b019229bdb555bd04d Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 7 Nov 2017 12:42:11 +1000
|
||||
Subject: [PATCH] Ticket 49377 - Incoming BER too large with TLS on plain port
|
||||
|
||||
Bug Description: When doing TLS to a plain port, a message of
|
||||
"ber element 3 bytes too large for max ber" when max ber > 3.
|
||||
|
||||
Fix Description: When ber_len < maxber, report that the request
|
||||
may be misformed instead of "oversize" instead. This can lead
|
||||
to a better diagnosis.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49377
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (thanks!)
|
||||
|
||||
Cherry picked from commit b3629af054760d9421a41d63b8b8ed513bb6944d
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 3f19b9765..8ef115691 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -2176,6 +2176,13 @@ log_ber_too_big_error(const Connection *conn, ber_len_t ber_len, ber_len_t maxbe
|
||||
" is %" BERLEN_T " bytes. Change the nsslapd-maxbersize attribute in"
|
||||
" cn=config to increase.\n",
|
||||
conn->c_connid, conn->c_sd, maxbersize);
|
||||
+ } else if (ber_len < maxbersize) {
|
||||
+ /* This means the request was misformed, not too large. */
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error",
|
||||
+ "conn=%" PRIu64 " fd=%d Incoming BER Element may be misformed. "
|
||||
+ "This may indicate an attempt to use TLS on a plaintext port, "
|
||||
+ "IE ldaps://localhost:389. Check your client LDAP_URI settings.\n",
|
||||
+ conn->c_connid, conn->c_sd);
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error",
|
||||
"conn=%" PRIu64 " fd=%d Incoming BER Element was %" BERLEN_T " bytes, max allowable"
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
From 127e0d954eb7741c4afdc0305f7970b7ea164e8d Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Thu, 9 Nov 2017 11:28:34 +0100
|
||||
Subject: [PATCH] Ticket 48118 - At startup, changelog can be erronously
|
||||
rebuilt after a normal shutdown
|
||||
|
||||
Problem: There are two problems that can lead to inconsistent database and changelog maxruv:
|
||||
1] the database ruv is written periodically in th ehouskeeping thread and at shutdown. It
|
||||
relies on teh ruv_dirty flag, but due to a race condition this can be reset befor writing
|
||||
the ruv
|
||||
2] the changelog max ruv is updated whenever an operation is commutted, but in case of internal
|
||||
operations inside the txn for a client operation, if the operation is aborted the cl maxruv
|
||||
is not reset. Since it is only written at shutdown this normally is no problem, but if the
|
||||
aborted operation is the last before shutdown or is aborted by shutdown the cl ruv is incorrect
|
||||
|
||||
Fix: the fix is in two parts:
|
||||
1] remove the use of the dirty flag, ensure that the ruv is always written. The overhead for writing
|
||||
a database ruv that has not changed is minimal
|
||||
2] when writing the changelog maxruv check if the macsns it contains are really present in the
|
||||
changelog. If not the maxruv is not written, it will be reconstructed at the next startup
|
||||
|
||||
Reviewed by: William,Thierry - Thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 39 ++++++++++++++++++++++
|
||||
ldap/servers/plugins/replication/repl5.h | 1 -
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 32 +-----------------
|
||||
.../plugins/replication/repl5_replica_config.c | 2 --
|
||||
4 files changed, 40 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index ec648c014..55032dfb0 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -250,6 +250,8 @@ static void _cl5ReadBerval(struct berval *bv, char **buff);
|
||||
static void _cl5WriteBerval(struct berval *bv, char **buff);
|
||||
static int _cl5ReadBervals(struct berval ***bv, char **buff, unsigned int size);
|
||||
static int _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size);
|
||||
+static int64_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv);
|
||||
+static int64_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg);
|
||||
|
||||
/* replay iteration */
|
||||
#ifdef FOR_DEBUGGING
|
||||
@@ -2716,6 +2718,36 @@ _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size)
|
||||
return CL5_SUCCESS;
|
||||
}
|
||||
|
||||
+static int64_t
|
||||
+_cl5CheckCSNinCL(const ruv_enum_data *element, void *arg)
|
||||
+{
|
||||
+ CL5DBFile *file = (CL5DBFile *)arg;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ DBT key = {0}, data = {0};
|
||||
+ char csnStr[CSN_STRSIZE];
|
||||
+
|
||||
+ /* construct the key */
|
||||
+ key.data = csn_as_string(element->csn, PR_FALSE, csnStr);
|
||||
+ key.size = CSN_STRSIZE;
|
||||
+
|
||||
+ data.flags = DB_DBT_MALLOC;
|
||||
+
|
||||
+ rc = file->db->get(file->db, NULL /*txn*/, &key, &data, 0);
|
||||
+
|
||||
+ slapi_ch_free(&(data.data));
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int64_t
|
||||
+_cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv)
|
||||
+{
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ rc = ruv_enumerate_elements(maxruv, _cl5CheckCSNinCL, (void *)file);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
/* upgrade from db33 to db41
|
||||
* 1. Run recovery on the database environment using the DB_ENV->open method
|
||||
* 2. Remove any Berkeley DB environment using the DB_ENV->remove method
|
||||
@@ -4010,6 +4042,13 @@ _cl5WriteRUV(CL5DBFile *file, PRBool purge)
|
||||
rc = ruv_to_bervals(file->maxRUV, &vals);
|
||||
}
|
||||
|
||||
+ if (!purge && _cl5CheckMaxRUV(file, file->maxRUV)) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
|
||||
+ "_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n",
|
||||
+ file->name);
|
||||
+ return CL5_DB_ERROR;
|
||||
+ }
|
||||
+
|
||||
key.size = CSN_STRSIZE;
|
||||
|
||||
rc = _cl5WriteBervals(vals, &buff, &data.size);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||
index c6e79b7e2..4e206a0fc 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||
@@ -725,7 +725,6 @@ Object *replica_get_for_backend(const char *be_name);
|
||||
void replica_set_purge_delay(Replica *r, uint32_t purge_delay);
|
||||
void replica_set_tombstone_reap_interval(Replica *r, long interval);
|
||||
void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv);
|
||||
-void replica_set_ruv_dirty(Replica *r);
|
||||
Slapi_Entry *get_in_memory_ruv(Slapi_DN *suffix_sdn);
|
||||
int replica_write_ruv(Replica *r);
|
||||
char *replica_get_dn(Replica *r);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index e5296bf1c..77f4f18e4 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -41,7 +41,6 @@ struct replica
|
||||
ReplicaType repl_type; /* is this replica read-only ? */
|
||||
ReplicaId repl_rid; /* replicaID */
|
||||
Object *repl_ruv; /* replica update vector */
|
||||
- PRBool repl_ruv_dirty; /* Dirty flag for ruv */
|
||||
CSNPL *min_csn_pl; /* Pending list for minimal CSN */
|
||||
void *csn_pl_reg_id; /* registration assignment for csn callbacks */
|
||||
unsigned long repl_state_flags; /* state flags */
|
||||
@@ -788,7 +787,6 @@ replica_set_ruv(Replica *r, RUV *ruv)
|
||||
}
|
||||
|
||||
r->repl_ruv = object_new((void *)ruv, (FNFree)ruv_destroy);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
|
||||
replica_unlock(r->repl_lock);
|
||||
}
|
||||
@@ -860,9 +858,6 @@ replica_update_ruv(Replica *r, const CSN *updated_csn, const char *replica_purl)
|
||||
"to update RUV for replica %s, csn = %s\n",
|
||||
slapi_sdn_get_dn(r->repl_root),
|
||||
csn_as_string(updated_csn, PR_FALSE, csn_str));
|
||||
- } else {
|
||||
- /* RUV updated - mark as dirty */
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
|
||||
@@ -1347,8 +1342,6 @@ replica_dump(Replica *r)
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tupdate dn: %s\n",
|
||||
updatedn_list ? updatedn_list : "not configured");
|
||||
slapi_ch_free_string(&updatedn_list);
|
||||
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\truv: %s configured and is %sdirty\n",
|
||||
- r->repl_ruv ? "" : "not", r->repl_ruv_dirty ? "" : "not ");
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tCSN generator: %s configured\n",
|
||||
r->repl_csngen ? "" : "not");
|
||||
/* JCMREPL - Dump Referrals */
|
||||
@@ -1675,7 +1668,6 @@ replica_check_for_data_reload(Replica *r, void *arg __attribute__((unused)))
|
||||
|
||||
ruv_force_csn_update_from_ruv(upper_bound_ruv, r_ruv,
|
||||
"Force update of database RUV (from CL RUV) -> ", SLAPI_LOG_NOTICE);
|
||||
- replica_set_ruv_dirty(r);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -2778,11 +2770,6 @@ replica_write_ruv(Replica *r)
|
||||
|
||||
replica_lock(r->repl_lock);
|
||||
|
||||
- if (!r->repl_ruv_dirty) {
|
||||
- replica_unlock(r->repl_lock);
|
||||
- return rc;
|
||||
- }
|
||||
-
|
||||
PR_ASSERT(r->repl_ruv);
|
||||
|
||||
ruv_to_smod((RUV *)object_get_data(r->repl_ruv), &smod);
|
||||
@@ -2817,14 +2804,10 @@ replica_write_ruv(Replica *r)
|
||||
/* ruv does not exist - create one */
|
||||
replica_lock(r->repl_lock);
|
||||
|
||||
- if (rc == LDAP_SUCCESS) {
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
- } else if (rc == LDAP_NO_SUCH_OBJECT) {
|
||||
+ if (rc == LDAP_NO_SUCH_OBJECT) {
|
||||
/* this includes an internal operation - but since this only happens
|
||||
during server startup - its ok that we have lock around it */
|
||||
rc = _replica_configure_ruv(r, PR_TRUE);
|
||||
- if (rc == 0)
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
} else /* error */
|
||||
{
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
@@ -3325,7 +3308,6 @@ replica_create_ruv_tombstone(Replica *r)
|
||||
|
||||
if (ruv_init_new(csnstr, r->repl_rid, purl, &ruv) == RUV_SUCCESS) {
|
||||
r->repl_ruv = object_new((void *)ruv, (FNFree)ruv_destroy);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
return_value = LDAP_SUCCESS;
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_create_ruv_tombstone - "
|
||||
@@ -3365,8 +3347,6 @@ replica_create_ruv_tombstone(Replica *r)
|
||||
slapi_add_internal_pb(pb);
|
||||
e = NULL; /* add consumes e, upon success or failure */
|
||||
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value);
|
||||
- if (return_value == LDAP_SUCCESS)
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
|
||||
done:
|
||||
slapi_entry_free(e);
|
||||
@@ -3630,7 +3610,6 @@ replica_strip_cleaned_rids(Replica *r)
|
||||
ruv_get_cleaned_rids(ruv, rid);
|
||||
while (rid[i] != 0) {
|
||||
ruv_delete_replica(ruv, rid[i]);
|
||||
- replica_set_ruv_dirty(r);
|
||||
if (replica_write_ruv(r)) {
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"replica_strip_cleaned_rids - Failed to write RUV\n");
|
||||
@@ -3744,15 +3723,6 @@ replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv)
|
||||
}
|
||||
}
|
||||
|
||||
-void
|
||||
-replica_set_ruv_dirty(Replica *r)
|
||||
-{
|
||||
- PR_ASSERT(r);
|
||||
- replica_lock(r->repl_lock);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
- replica_unlock(r->repl_lock);
|
||||
-}
|
||||
-
|
||||
PRBool
|
||||
replica_is_state_flag_set(Replica *r, int32_t flag)
|
||||
{
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 9c8d6adbb..e025f34d8 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -937,7 +937,6 @@ replica_config_change_type_and_id(Replica *r, const char *new_type, const char *
|
||||
replica_reset_csn_pl(r);
|
||||
}
|
||||
ruv_delete_replica(ruv, oldrid);
|
||||
- replica_set_ruv_dirty(r);
|
||||
cl5CleanRUV(oldrid);
|
||||
replica_set_csn_assigned(r);
|
||||
}
|
||||
@@ -1323,7 +1322,6 @@ replica_execute_cleanruv_task(Object *r, ReplicaId rid, char *returntext __attri
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
rc = ruv_delete_replica(local_ruv, rid);
|
||||
- replica_set_ruv_dirty(replica);
|
||||
if (replica_write_ruv(replica)) {
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task - Could not write RUV\n");
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From fd06b282ffd06a5b3807c0396bff442f0c7568b1 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Wed, 15 Nov 2017 13:17:00 +0100
|
||||
Subject: [PATCH] Ticket 48118 - fix compiler warning for incorrect return type
|
||||
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index 55032dfb0..721013abf 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -250,8 +250,8 @@ static void _cl5ReadBerval(struct berval *bv, char **buff);
|
||||
static void _cl5WriteBerval(struct berval *bv, char **buff);
|
||||
static int _cl5ReadBervals(struct berval ***bv, char **buff, unsigned int size);
|
||||
static int _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size);
|
||||
-static int64_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv);
|
||||
-static int64_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg);
|
||||
+static int32_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv);
|
||||
+static int32_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg);
|
||||
|
||||
/* replay iteration */
|
||||
#ifdef FOR_DEBUGGING
|
||||
@@ -2718,7 +2718,7 @@ _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size)
|
||||
return CL5_SUCCESS;
|
||||
}
|
||||
|
||||
-static int64_t
|
||||
+static int32_t
|
||||
_cl5CheckCSNinCL(const ruv_enum_data *element, void *arg)
|
||||
{
|
||||
CL5DBFile *file = (CL5DBFile *)arg;
|
||||
@@ -2739,7 +2739,7 @@ _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int64_t
|
||||
+static int32_t
|
||||
_cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv)
|
||||
{
|
||||
int rc = 0;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
From e3dea0043973faf42f7756d840bc55aa8f143eb1 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Wed, 15 Nov 2017 13:44:02 +1000
|
||||
Subject: [PATCH] Ticket 49298 - Correct error codes with config restore.
|
||||
|
||||
Bug Description: The piece of code uses 0 as an error - not 1,
|
||||
and in some cases did not even check the codes or use the
|
||||
correct logic.
|
||||
|
||||
Fix Description: Cleanup dse_check_file to better check the
|
||||
content of files and communicate issues to the admin. Correct
|
||||
slapd_bootstrap_config to correctly handle the cases of removal
|
||||
and restore.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49298
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynoolds & spichugi
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
(cherry picked from commit 75e55e26579955adf058e8adcba9a28779583b7b)
|
||||
---
|
||||
.../suites/config/removed_config_49298_test.py | 81 ++++++++++++++++++++++
|
||||
ldap/servers/slapd/config.c | 15 ++--
|
||||
ldap/servers/slapd/dse.c | 42 ++++++++---
|
||||
3 files changed, 119 insertions(+), 19 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/config/removed_config_49298_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/config/removed_config_49298_test.py b/dirsrvtests/tests/suites/config/removed_config_49298_test.py
|
||||
new file mode 100644
|
||||
index 000000000..e65236924
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/config/removed_config_49298_test.py
|
||||
@@ -0,0 +1,81 @@
|
||||
+# --- BEGIN COPYRIGHT BLOCK ---
|
||||
+# Copyright (C) 2017 Red Hat, Inc.
|
||||
+# All rights reserved.
|
||||
+#
|
||||
+# License: GPL (version 3 or any later version).
|
||||
+# See LICENSE for details.
|
||||
+# --- END COPYRIGHT BLOCK ---
|
||||
+#
|
||||
+import pytest
|
||||
+import os
|
||||
+import logging
|
||||
+import subprocess
|
||||
+
|
||||
+from lib389.topologies import topology_st 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__)
|
||||
+
|
||||
+def test_restore_config(topo):
|
||||
+ """
|
||||
+ Check that if a dse.ldif and backup are removed, that the server still starts.
|
||||
+
|
||||
+ :id: e1c38fa7-30bc-46f2-a934-f8336f387581
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1. Stop the instance
|
||||
+ 2. Delete 'dse.ldif'
|
||||
+ 3. Start the instance
|
||||
+ :expectedresults:
|
||||
+ 1. Steps 1 and 2 succeed.
|
||||
+ 2. Server will succeed to start with restored cfg.
|
||||
+ """
|
||||
+ topo.standalone.stop()
|
||||
+
|
||||
+ dse_path = topo.standalone.get_config_dir()
|
||||
+
|
||||
+ log.info(dse_path)
|
||||
+
|
||||
+ for i in ('dse.ldif', 'dse.ldif.startOK'):
|
||||
+ p = os.path.join(dse_path, i)
|
||||
+ os.remove(p)
|
||||
+
|
||||
+ # This will pass.
|
||||
+ topo.standalone.start()
|
||||
+
|
||||
+def test_removed_config(topo):
|
||||
+ """
|
||||
+ Check that if a dse.ldif and backup are removed, that the server
|
||||
+ exits better than "segfault".
|
||||
+
|
||||
+ :id: b45272d1-c197-473e-872f-07257fcb2ec0
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1. Stop the instance
|
||||
+ 2. Delete 'dse.ldif', 'dse.ldif.bak', 'dse.ldif.startOK'
|
||||
+ 3. Start the instance
|
||||
+ :expectedresults:
|
||||
+ 1. Steps 1 and 2 succeed.
|
||||
+ 2. Server will fail to start, but will not crash.
|
||||
+ """
|
||||
+ topo.standalone.stop()
|
||||
+
|
||||
+ dse_path = topo.standalone.get_config_dir()
|
||||
+
|
||||
+ log.info(dse_path)
|
||||
+
|
||||
+ for i in ('dse.ldif', 'dse.ldif.bak', 'dse.ldif.startOK'):
|
||||
+ p = os.path.join(dse_path, i)
|
||||
+ os.remove(p)
|
||||
+
|
||||
+ # We actually can't check the log output, because it can't read dse.ldif,
|
||||
+ # don't know where to write it yet! All we want is the server fail to
|
||||
+ # start here, rather than infinite run + segfault.
|
||||
+ with pytest.raises(subprocess.CalledProcessError):
|
||||
+ topo.standalone.start()
|
||||
+
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c
|
||||
index afe07df84..c8d57e747 100644
|
||||
--- a/ldap/servers/slapd/config.c
|
||||
+++ b/ldap/servers/slapd/config.c
|
||||
@@ -121,14 +121,13 @@ slapd_bootstrap_config(const char *configdir)
|
||||
"Passed null config directory\n");
|
||||
return rc; /* Fail */
|
||||
}
|
||||
- PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir,
|
||||
- CONFIG_FILENAME);
|
||||
- PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir,
|
||||
- CONFIG_FILENAME);
|
||||
- if ((rc = dse_check_file(configfile, tmpfile)) == 0) {
|
||||
- PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.bak", configdir,
|
||||
- CONFIG_FILENAME);
|
||||
- rc = dse_check_file(configfile, tmpfile);
|
||||
+ PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir, CONFIG_FILENAME);
|
||||
+ PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.bak", configdir, CONFIG_FILENAME);
|
||||
+ rc = dse_check_file(configfile, tmpfile);
|
||||
+ if (rc == 0) {
|
||||
+ /* EVERYTHING IS GOING WRONG, ARRGHHHHHH */
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "slapd_bootstrap_config", "No valid configurations can be accessed! You must restore %s from backup!\n", configfile);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
if ((rc = PR_GetFileInfo64(configfile, &prfinfo)) != PR_SUCCESS) {
|
||||
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
||||
index 420248c24..653009f53 100644
|
||||
--- a/ldap/servers/slapd/dse.c
|
||||
+++ b/ldap/servers/slapd/dse.c
|
||||
@@ -609,29 +609,49 @@ dse_check_file(char *filename, char *backupname)
|
||||
|
||||
if (PR_GetFileInfo64(filename, &prfinfo) == PR_SUCCESS) {
|
||||
if (prfinfo.size > 0) {
|
||||
- return (1);
|
||||
+ /* File exists and has content. */
|
||||
+ return 1;
|
||||
} else {
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
+ "The config %s has zero length. Attempting restore ... \n", filename, rc);
|
||||
rc = PR_Delete(filename);
|
||||
}
|
||||
+ } else {
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
+ "The config %s can not be accessed. Attempting restore ... (reason: %d)\n", filename, rc);
|
||||
}
|
||||
|
||||
if (backupname) {
|
||||
+
|
||||
+ if (PR_GetFileInfo64(backupname, &prfinfo) != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
+ "The backup %s can not be accessed. Check it exists and permissions.\n", backupname);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (prfinfo.size <= 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "dse_check_file",
|
||||
+ "The backup file %s has zero length, refusing to restore it.\n", backupname);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
rc = PR_Rename(backupname, filename);
|
||||
- } else {
|
||||
- return (0);
|
||||
- }
|
||||
+ if (rc != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
+ "The configuration file %s was NOT able to be restored from %s, error %d\n", filename, backupname, rc);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
- if (PR_GetFileInfo64(filename, &prfinfo) == PR_SUCCESS && prfinfo.size > 0) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
- "The configuration file %s was restored from backup %s\n", filename, backupname);
|
||||
- return (1);
|
||||
+ "The configuration file %s was restored from backup %s\n", filename, backupname);
|
||||
+ return 1;
|
||||
+
|
||||
} else {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "dse_check_file",
|
||||
- "The configuration file %s was not restored from backup %s, error %d\n",
|
||||
- filename, backupname, rc);
|
||||
- return (0);
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", "No backup filename provided.\n");
|
||||
+ return 0;
|
||||
}
|
||||
}
|
||||
+
|
||||
static int
|
||||
dse_read_one_file(struct dse *pdse, const char *filename, Slapi_PBlock *pb, int primary_file)
|
||||
{
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
From bfaf5b56bb1a416c5e058a9925642098c87e0330 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Thu, 30 Nov 2017 14:06:59 +0100
|
||||
Subject: [PATCH] Ticket 49474 - sasl allow mechs does not operate correctly
|
||||
|
||||
Bug Description: In a fix to sasl allowed mechs, the logic
|
||||
was not properly configured.
|
||||
|
||||
Fix Description: Alter the ids_sasl_supported_mech to be
|
||||
clearer and simpler in it's design.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49474
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: tbordaz (Thank you!)
|
||||
|
||||
Cherry picked from f75cfbce07b79272a7f1a2e387dc232d45c169f5
|
||||
---
|
||||
ldap/servers/slapd/saslbind.c | 49 ++++++++-----------------------------------
|
||||
1 file changed, 9 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 6734c32a7..67da97148 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -835,52 +835,21 @@ ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
static int
|
||||
ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
|
||||
{
|
||||
- int i, ret = 0;
|
||||
- char **mechs;
|
||||
- char **allowed_mechs = NULL;
|
||||
- char *dupstr;
|
||||
- const char *str;
|
||||
- int sasl_result = 0;
|
||||
- Connection *pb_conn = NULL;
|
||||
-
|
||||
- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
- sasl_conn_t *sasl_conn = (sasl_conn_t *)pb_conn->c_sasl_conn;
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "=>\n");
|
||||
|
||||
- /* sasl_listmech is not thread-safe - caller must lock pb_conn */
|
||||
- sasl_result = sasl_listmech(sasl_conn,
|
||||
- NULL, /* username */
|
||||
- "", ",", "",
|
||||
- &str, NULL, NULL);
|
||||
- if (sasl_result != SASL_OK) {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- dupstr = slapi_ch_strdup(str);
|
||||
- mechs = slapi_str2charray(dupstr, ",");
|
||||
- allowed_mechs = config_get_allowed_sasl_mechs_array();
|
||||
+ char **allowed_mechs = ids_sasl_listmech(pb);
|
||||
|
||||
- for (i = 0; mechs[i] != NULL; i++) {
|
||||
- if (strcasecmp(mech, mechs[i]) == 0) {
|
||||
- if (allowed_mechs) {
|
||||
- if (charray_inlist(allowed_mechs, (char *)mech) == 0) {
|
||||
- ret = 1;
|
||||
- }
|
||||
- break;
|
||||
- } else {
|
||||
- ret = 1;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
+ /* 0 indicates "now allowed" */
|
||||
+ int allowed_mech_present = 0;
|
||||
+ if (allowed_mechs != NULL) {
|
||||
+ /* Returns 1 if present and allowed. */
|
||||
+ allowed_mech_present = charray_inlist(allowed_mechs, (char *)mech);
|
||||
+ charray_free(allowed_mechs);
|
||||
}
|
||||
|
||||
- charray_free(allowed_mechs);
|
||||
- charray_free(mechs);
|
||||
- slapi_ch_free((void **)&dupstr);
|
||||
-
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n");
|
||||
|
||||
- return ret;
|
||||
+ return allowed_mech_present;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -944,7 +913,7 @@ ids_sasl_check_bind(Slapi_PBlock *pb)
|
||||
* different error code to SASL_NOMECH. Must be called
|
||||
* while holding the pb_conn lock
|
||||
*/
|
||||
- if (!ids_sasl_mech_supported(pb, mech)) {
|
||||
+ if (ids_sasl_mech_supported(pb, mech) == 0) {
|
||||
rc = SASL_NOMECH;
|
||||
goto sasl_check_result;
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
From 30fa0e4c993d4a91a90327329b50f02e637fe049 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 28 Nov 2017 15:31:25 +0100
|
||||
Subject: [PATCH] Ticket 49470 - overflow in pblock_get
|
||||
|
||||
Bug Description: While getting the connection id we used an int
|
||||
not a uint64_t
|
||||
|
||||
Fix Description: Make the stack size uint64_t instead.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49470
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: tbordaz
|
||||
---
|
||||
ldap/servers/slapd/modify.c | 5 +++--
|
||||
ldap/servers/slapd/pblock.c | 4 ++--
|
||||
ldap/servers/slapd/slap.h | 2 +-
|
||||
3 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
|
||||
index 6309975ae..0dcac646b 100644
|
||||
--- a/ldap/servers/slapd/modify.c
|
||||
+++ b/ldap/servers/slapd/modify.c
|
||||
@@ -281,11 +281,12 @@ do_modify(Slapi_PBlock *pb)
|
||||
|
||||
if (ignored_some_mods && (0 == smods.num_elements)) {
|
||||
if (pb_conn->c_isreplication_session) {
|
||||
- int connid, opid;
|
||||
+ uint64_t connid;
|
||||
+ int32_t opid;
|
||||
slapi_pblock_get(pb, SLAPI_CONN_ID, &connid);
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION_ID, &opid);
|
||||
slapi_log_err(SLAPI_LOG_ERR, "do_modify",
|
||||
- "Rejecting replicated password policy operation(conn=%d op=%d) for "
|
||||
+ "Rejecting replicated password policy operation(conn=%"PRIu64" op=%d) for "
|
||||
"entry %s. To allow these changes to be accepted, set passwordIsGlobalPolicy to 'on' in "
|
||||
"cn=config.\n",
|
||||
connid, opid, rawdn);
|
||||
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
|
||||
index 8f87de5b5..4514c3ce6 100644
|
||||
--- a/ldap/servers/slapd/pblock.c
|
||||
+++ b/ldap/servers/slapd/pblock.c
|
||||
@@ -412,7 +412,7 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
||||
"slapi_pblock_get", "Connection is NULL and hence cannot access SLAPI_CONN_ID \n");
|
||||
return (-1);
|
||||
}
|
||||
- (*(PRUint64 *)value) = pblock->pb_conn->c_connid;
|
||||
+ (*(uint64_t *)value) = pblock->pb_conn->c_connid;
|
||||
break;
|
||||
case SLAPI_CONN_DN:
|
||||
/*
|
||||
@@ -2538,7 +2538,7 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value)
|
||||
"slapi_pblock_set", "Connection is NULL and hence cannot access SLAPI_CONN_ID \n");
|
||||
return (-1);
|
||||
}
|
||||
- pblock->pb_conn->c_connid = *((PRUint64 *)value);
|
||||
+ pblock->pb_conn->c_connid = *((uint64_t *)value);
|
||||
break;
|
||||
case SLAPI_CONN_DN:
|
||||
/*
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 44632580a..830944f72 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1604,7 +1604,7 @@ typedef struct conn
|
||||
int c_gettingber; /* in the middle of ber_get_next */
|
||||
BerElement *c_currentber; /* ber we're getting */
|
||||
time_t c_starttime; /* when the connection was opened */
|
||||
- PRUint64 c_connid; /* id of this connection for stats*/
|
||||
+ uint64_t c_connid; /* id of this connection for stats*/
|
||||
PRUint64 c_maxthreadscount; /* # of times a conn hit max threads */
|
||||
PRUint64 c_maxthreadsblocked; /* # of operations blocked by maxthreads */
|
||||
int c_opsinitiated; /* # ops initiated/next op id */
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
From 25844922007eea26f78d18171e51be3aa7b5e949 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 6 Dec 2017 15:14:57 +0100
|
||||
Subject: [PATCH] Ticket 49471 - heap-buffer-overflow in ss_unescape
|
||||
|
||||
Bug Description:
|
||||
Two problems here
|
||||
- when searching for wildcard and escape char, ss_unescape assumes the string
|
||||
is at least 3 chars longs. So memcmp can overflow a shorter string
|
||||
- while splitting a string into substring pattern, it loops over
|
||||
wildcard and can overpass the string end
|
||||
|
||||
Fix Description:
|
||||
For the first problem, it checks the string size is long enough to memcmp
|
||||
a wildcard or an escape
|
||||
For the second it exits from the loop as soon as the end of the string is reached
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49471
|
||||
|
||||
Reviewed by: William Brown
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
|
||||
(cherry picked from commit 5991388ce75fba8885579b769711d57acfd43cd3)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49471_test.py | 79 +++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/collation/orfilter.c | 14 +++--
|
||||
2 files changed, 87 insertions(+), 6 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49471_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49471_test.py b/dirsrvtests/tests/tickets/ticket49471_test.py
|
||||
new file mode 100644
|
||||
index 000000000..0456a5182
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49471_test.py
|
||||
@@ -0,0 +1,79 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import time
|
||||
+import ldap
|
||||
+from lib389._constants import *
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+from lib389 import Entry
|
||||
+
|
||||
+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__)
|
||||
+
|
||||
+
|
||||
+USER_CN='user_'
|
||||
+def _user_get_dn(no):
|
||||
+ cn = '%s%d' % (USER_CN, no)
|
||||
+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
|
||||
+ return (cn, dn)
|
||||
+
|
||||
+def add_user(server, no, desc='dummy', sleep=True):
|
||||
+ (cn, dn) = _user_get_dn(no)
|
||||
+ log.fatal('Adding user (%s): ' % dn)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser', 'userSecurityInformation'],
|
||||
+ 'cn': [cn],
|
||||
+ 'description': [desc],
|
||||
+ 'sn': [cn],
|
||||
+ 'description': ['add on that host']})))
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def test_ticket49471(topo):
|
||||
+ """Specify a test case purpose or name here
|
||||
+
|
||||
+ :id: 457ab172-9455-4eb2-89a0-150e3de5993f
|
||||
+ :setup: Fill in set up configuration here
|
||||
+ :steps:
|
||||
+ 1. Fill in test case steps here
|
||||
+ 2. And indent them like this (RST format requirement)
|
||||
+ :expectedresults:
|
||||
+ 1. Fill in the result that is expected
|
||||
+ 2. For each test step
|
||||
+ """
|
||||
+
|
||||
+ # If you need any test suite initialization,
|
||||
+ # please, write additional fixture for that (including finalizer).
|
||||
+ # Topology for suites are predefined in lib389/topologies.py.
|
||||
+
|
||||
+ # If you need host, port or any other data about instance,
|
||||
+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
|
||||
+
|
||||
+ S1 = topo.standalone
|
||||
+ add_user(S1, 1)
|
||||
+
|
||||
+ Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*on\*)"
|
||||
+ ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter)
|
||||
+ assert len(ents) == 1
|
||||
+
|
||||
+ #
|
||||
+ # The following is for the test 49491
|
||||
+ # skipped here else it crashes in ASAN
|
||||
+ #Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*host)"
|
||||
+ #ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter)
|
||||
+ #assert len(ents) == 1
|
||||
+
|
||||
+ if DEBUGGING:
|
||||
+ # Add debugging steps(if any)...
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c
|
||||
index 5a2d8a0ab..a98d90219 100644
|
||||
--- a/ldap/servers/plugins/collation/orfilter.c
|
||||
+++ b/ldap/servers/plugins/collation/orfilter.c
|
||||
@@ -313,12 +313,12 @@ ss_unescape(struct berval *val)
|
||||
char *t = s;
|
||||
char *limit = s + val->bv_len;
|
||||
while (s < limit) {
|
||||
- if (!memcmp(s, "\\2a", 3) ||
|
||||
- !memcmp(s, "\\2A", 3)) {
|
||||
+ if (((limit - s) >= 3) &&
|
||||
+ (!memcmp(s, "\\2a", 3) || !memcmp(s, "\\2A", 3))) {
|
||||
*t++ = WILDCARD;
|
||||
s += 3;
|
||||
- } else if (!memcmp(s, "\\5c", 3) ||
|
||||
- !memcmp(s, "\\5C", 3)) {
|
||||
+ } else if ((limit - s) >= 3 &&
|
||||
+ (!memcmp(s, "\\5c", 3) || !memcmp(s, "\\5C", 3))) {
|
||||
*t++ = '\\';
|
||||
s += 3;
|
||||
} else {
|
||||
@@ -409,13 +409,15 @@ ss_filter_values(struct berval *pattern, int *query_op)
|
||||
switch (*p) {
|
||||
case WILDCARD:
|
||||
result[n++] = ss_filter_value(s, p - s, &val);
|
||||
- while (++p != plimit && *p == WILDCARD)
|
||||
- ;
|
||||
+ while (p != plimit && *p == WILDCARD) p++;
|
||||
s = p;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ if (p >= plimit) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
if (p != s || s == plimit) {
|
||||
result[n++] = ss_filter_value(s, p - s, &val);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 189c3ce4d5b5c9341a60d4056dad26133d9607ca Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Fri, 17 Nov 2017 11:43:36 +1000
|
||||
Subject: [PATCH] Ticket 49298 - fix complier warn
|
||||
|
||||
Bug Description: Extra argument to error log in dse.c
|
||||
|
||||
Fix Description: Remove extra argument.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49298
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: oneline rule.
|
||||
---
|
||||
ldap/servers/slapd/dse.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
||||
index 653009f53..662e91aa7 100644
|
||||
--- a/ldap/servers/slapd/dse.c
|
||||
+++ b/ldap/servers/slapd/dse.c
|
||||
@@ -613,7 +613,7 @@ dse_check_file(char *filename, char *backupname)
|
||||
return 1;
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "dse_check_file",
|
||||
- "The config %s has zero length. Attempting restore ... \n", filename, rc);
|
||||
+ "The config %s has zero length. Attempting restore ... \n", filename);
|
||||
rc = PR_Delete(filename);
|
||||
}
|
||||
} else {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
From 2c56e7dc08a41fc1dfa6a79213e93686f553847c Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 11 Dec 2017 15:48:24 +0100
|
||||
Subject: [PATCH] Ticket 49495 - Fix memory management is vattr.
|
||||
|
||||
Bug Description: During the fix for
|
||||
https://pagure.io/389-ds-base/issue/49436 a issue was exposed
|
||||
in how registration of attributes to cos work. With the change
|
||||
to handle -> attr link, this exposed that cos treats each attribute
|
||||
and template pair as a new type for the handle. As aresult, this
|
||||
caused the sp_list to create a long linked list of M*N entries
|
||||
for each attr - template value. Obviously, this is extremely
|
||||
slow to traverse during a search!
|
||||
|
||||
Fix Description: Undo part of the SLL next change and convert
|
||||
to reference counting. The issue remains that there is a defect
|
||||
in how cos handles attribute registration, but this can not be
|
||||
resolved without a significant rearchitecture of the code
|
||||
related to virtual attributes.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49495
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: tbordaz, lkrispen (Thanks!)
|
||||
---
|
||||
ldap/servers/plugins/cos/cos_cache.c | 28 +++++++++++-----------------
|
||||
ldap/servers/slapd/vattr.c | 23 +++++++++++++++++++++--
|
||||
2 files changed, 32 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index 662dace35..3b3c05783 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -275,7 +275,7 @@ static Slapi_Mutex *start_lock;
|
||||
static Slapi_Mutex *stop_lock;
|
||||
static Slapi_CondVar *something_changed = NULL;
|
||||
static Slapi_CondVar *start_cond = NULL;
|
||||
-
|
||||
+static vattr_sp_handle *vattr_handle = NULL;
|
||||
|
||||
/*
|
||||
cos_cache_init
|
||||
@@ -314,6 +314,15 @@ cos_cache_init(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
+ cos_cache_vattr_get,
|
||||
+ cos_cache_vattr_compare,
|
||||
+ cos_cache_vattr_types) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider\n");
|
||||
+ ret = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* grab the views interface */
|
||||
if (slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) {
|
||||
/* lets be tolerant if views is disabled */
|
||||
@@ -847,22 +856,7 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data)
|
||||
dnVals[valIndex]->bv_val);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Each SP_handle is associated to one and only one vattr.
|
||||
- * We could consider making this a single function rather
|
||||
- * than the double-call.
|
||||
- */
|
||||
-
|
||||
- vattr_sp_handle *vattr_handle = NULL;
|
||||
-
|
||||
- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
- cos_cache_vattr_get,
|
||||
- cos_cache_vattr_compare,
|
||||
- cos_cache_vattr_types) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val);
|
||||
- } else {
|
||||
- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
- }
|
||||
+ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
|
||||
} /* if(attrType is cosAttribute) */
|
||||
|
||||
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||||
index 432946c79..13e527188 100644
|
||||
--- a/ldap/servers/slapd/vattr.c
|
||||
+++ b/ldap/servers/slapd/vattr.c
|
||||
@@ -1544,6 +1544,7 @@ struct _vattr_sp_handle
|
||||
vattr_sp *sp;
|
||||
struct _vattr_sp_handle *next; /* So we can link them together in the map */
|
||||
void *hint; /* Hint to the SP */
|
||||
+ uint64_t rc;
|
||||
};
|
||||
|
||||
/* Calls made by Service Providers */
|
||||
@@ -1770,7 +1771,7 @@ is a separate thing in the insterests of stability.
|
||||
|
||||
*/
|
||||
|
||||
-#define VARRT_MAP_HASHTABLE_SIZE 10
|
||||
+#define VARRT_MAP_HASHTABLE_SIZE 32
|
||||
|
||||
/* Attribute map oject */
|
||||
/* Needs to contain: a linked list of pointers to provider handles handles,
|
||||
@@ -1867,7 +1868,10 @@ vattr_map_entry_free(vattr_map_entry *vae)
|
||||
vattr_sp_handle *list_entry = vae->sp_list;
|
||||
while (list_entry != NULL) {
|
||||
vattr_sp_handle *next_entry = list_entry->next;
|
||||
- slapi_ch_free((void **)&list_entry);
|
||||
+ if (slapi_atomic_decr_64(&(list_entry->rc), __ATOMIC_RELAXED) == 0) {
|
||||
+ /* Only free on RC 0 */
|
||||
+ slapi_ch_free((void **)&list_entry);
|
||||
+ }
|
||||
list_entry = next_entry;
|
||||
}
|
||||
slapi_ch_free_string(&(vae->type_name));
|
||||
@@ -2280,6 +2284,17 @@ to handle the calls on it, but return nothing */
|
||||
*
|
||||
* Better idea, is that regattr should just take the fn pointers
|
||||
* and callers never *see* the sp_handle structure at all.
|
||||
+ *
|
||||
+ * This leaves us with some quirks today. First: if you have plugin A
|
||||
+ * and B, A registers attr 1 and B 1 and 2, it's possible that if you
|
||||
+ * register A1 first, then B1, you have B->A in next. Then when you
|
||||
+ * register B2, because we take 0==result from map_lookup, we add sp
|
||||
+ * "as is" to the map. This means that B2 now has the same next to A1
|
||||
+ * handle. This won't add a bug, because A1 won't be able to service the
|
||||
+ * attr, but it could cause some head scratching ...
|
||||
+ *
|
||||
+ * Again, to fix this, the whole vattr external interface needs a
|
||||
+ * redesign ... :(
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -2304,11 +2319,15 @@ vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint)
|
||||
if (found) {
|
||||
return 0;
|
||||
}
|
||||
+ /* Increase the ref count of the sphandle */
|
||||
+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED);
|
||||
/* We insert the SP handle into the linked list at the head */
|
||||
sp->next = map_entry->sp_list;
|
||||
map_entry->sp_list = sp;
|
||||
} else {
|
||||
/* If not, add it */
|
||||
+ /* Claim a reference on the sp ... */
|
||||
+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED);
|
||||
map_entry = vattr_map_entry_new(type_to_add, sp, hint);
|
||||
if (NULL == map_entry) {
|
||||
return ENOMEM;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
From 0c1fbfaf77d6f7b2a6628deaf309bbe1c3e7a8e8 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 28 Nov 2017 13:39:19 +0100
|
||||
Subject: [PATCH] Ticket 48184 - close connections at shutdown cleanly.
|
||||
|
||||
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.
|
||||
|
||||
Fix Description: Close connections during shutdown rather than
|
||||
leaving them alive.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48184
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: lkrispen, vashirov (Thank you!)
|
||||
---
|
||||
ldap/servers/slapd/conntable.c | 13 +++++++
|
||||
ldap/servers/slapd/daemon.c | 77 ++++++++++++++++++++++++++----------------
|
||||
ldap/servers/slapd/fe.h | 1 +
|
||||
ldap/servers/slapd/slap.h | 1 +
|
||||
4 files changed, 63 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||
index 7c57b47cd..f2f763dfa 100644
|
||||
--- a/ldap/servers/slapd/conntable.c
|
||||
+++ b/ldap/servers/slapd/conntable.c
|
||||
@@ -91,6 +91,19 @@ connection_table_abandon_all_operations(Connection_Table *ct)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+connection_table_disconnect_all(Connection_Table *ct)
|
||||
+{
|
||||
+ for (size_t i = 0; i < ct->size; i++) {
|
||||
+ if (ct->c[i].c_mutex) {
|
||||
+ Connection *c = &(ct->c[i]);
|
||||
+ PR_EnterMonitor(c->c_mutex);
|
||||
+ disconnect_server_nomutex(c, c->c_connid, -1, SLAPD_DISCONNECT_ABORT, ECANCELED);
|
||||
+ PR_ExitMonitor(c->c_mutex);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Given a file descriptor for a socket, this function will return
|
||||
* a slot in the connection table to use.
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index 4e0466ab3..c245a4d4e 100644
|
||||
--- a/ldap/servers/slapd/daemon.c
|
||||
+++ b/ldap/servers/slapd/daemon.c
|
||||
@@ -1176,6 +1176,30 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
|
||||
housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
|
||||
disk_monitoring_stop();
|
||||
|
||||
+ /*
|
||||
+ * Now that they are abandonded, we need to mark them as done.
|
||||
+ * In NS while it's safe to allow excess jobs to be cleaned by
|
||||
+ * by the walk and ns_job_done of remaining queued events, the
|
||||
+ * issue is that if we allow something to live past this point
|
||||
+ * the CT is freed from underneath, and bad things happen (tm).
|
||||
+ *
|
||||
+ * NOTE: We do this after we stop psearch, because there could
|
||||
+ * be a race between flagging the psearch done, and users still
|
||||
+ * try to send on the connection. Similar with op_threads.
|
||||
+ */
|
||||
+ connection_table_disconnect_all(the_connection_table);
|
||||
+
|
||||
+ /*
|
||||
+ * WARNING: Normally we should close the tp in main
|
||||
+ * but because of issues in the current connection design
|
||||
+ * we need to close it here to guarantee events won't fire!
|
||||
+ *
|
||||
+ * All the connection close jobs "should" complete before
|
||||
+ * shutdown at least.
|
||||
+ */
|
||||
+ ns_thrpool_shutdown(tp);
|
||||
+ ns_thrpool_wait(tp);
|
||||
+
|
||||
threads = g_get_active_threadcnt();
|
||||
if (threads > 0) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "slapd_daemon",
|
||||
@@ -1628,23 +1652,18 @@ ns_handle_closure(struct ns_job_t *job)
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
int do_yield = 0;
|
||||
|
||||
-/* this function must be called from the event loop thread */
|
||||
-#ifdef DEBUG
|
||||
- PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
-#else
|
||||
- /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
- if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_closure", "Attempt to close outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
- c->c_connid, c->c_sd);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
PR_EnterMonitor(c->c_mutex);
|
||||
+ /* Assert we really have the right job state. */
|
||||
+ PR_ASSERT(job == c->c_job);
|
||||
+
|
||||
connection_release_nolock_ext(c, 1); /* release ref acquired for event framework */
|
||||
PR_ASSERT(c->c_ns_close_jobs == 1); /* should be exactly 1 active close job - this one */
|
||||
c->c_ns_close_jobs--; /* this job is processing closure */
|
||||
+ /* Because handle closure will add a new job, we need to detach our current one. */
|
||||
+ c->c_job = NULL;
|
||||
do_yield = ns_handle_closure_nomutex(c);
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
+ /* Remove this task now. */
|
||||
ns_job_done(job);
|
||||
if (do_yield) {
|
||||
/* closure not done - another reference still outstanding */
|
||||
@@ -1667,6 +1686,14 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Cancel any existing ns jobs we have registered.
|
||||
+ */
|
||||
+ if (conn->c_job != NULL) {
|
||||
+ ns_job_done(conn->c_job);
|
||||
+ conn->c_job = NULL;
|
||||
+ }
|
||||
+
|
||||
if (CONN_NEEDS_CLOSING(conn)) {
|
||||
/* there should only ever be 0 or 1 active closure jobs */
|
||||
PR_ASSERT((conn->c_ns_close_jobs == 0) || (conn->c_ns_close_jobs == 1));
|
||||
@@ -1676,13 +1703,10 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
conn->c_connid, conn->c_sd);
|
||||
return;
|
||||
} else {
|
||||
- /* just make sure we schedule the event to be closed in a timely manner */
|
||||
- tv.tv_sec = 0;
|
||||
- tv.tv_usec = slapd_wakeup_timer * 1000;
|
||||
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 */
|
||||
- ns_result_t job_result = ns_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
|
||||
- ns_handle_closure, conn, NULL);
|
||||
+ /* Close the job asynchronously. Why? */
|
||||
+ ns_result_t job_result = ns_add_job(conn->c_tp, NS_JOB_TIMER, ns_handle_closure, conn, &(conn->c_job));
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post closure job "
|
||||
@@ -1726,7 +1750,7 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
#endif
|
||||
ns_result_t job_result = ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
|
||||
NS_JOB_READ | NS_JOB_PRESERVE_FD,
|
||||
- ns_handle_pr_read_ready, conn, NULL);
|
||||
+ ns_handle_pr_read_ready, conn, &(conn->c_job));
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
@@ -1755,19 +1779,13 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
int maxthreads = config_get_maxthreadsperconn();
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
|
||||
-/* this function must be called from the event loop thread */
|
||||
-#ifdef DEBUG
|
||||
- PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
-#else
|
||||
- /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
- if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "Attempt to handle read ready outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
- c->c_connid, c->c_sd);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
PR_EnterMonitor(c->c_mutex);
|
||||
+ /* Assert we really have the right job state. */
|
||||
+ PR_ASSERT(job == c->c_job);
|
||||
+
|
||||
+ /* On all code paths we remove the job, so set it null now */
|
||||
+ c->c_job = NULL;
|
||||
+
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "activity on conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
/* if we were called due to some i/o event, see what the state of the socket is */
|
||||
@@ -1826,6 +1844,7 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "queued conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
}
|
||||
+ /* Since we call done on the job, we need to remove it here. */
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
ns_job_done(job);
|
||||
return;
|
||||
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
|
||||
index 4d25a9fb8..f47bb6145 100644
|
||||
--- a/ldap/servers/slapd/fe.h
|
||||
+++ b/ldap/servers/slapd/fe.h
|
||||
@@ -100,6 +100,7 @@ extern Connection_Table *the_connection_table; /* JCM - Exported from globals.c
|
||||
Connection_Table *connection_table_new(int table_size);
|
||||
void connection_table_free(Connection_Table *ct);
|
||||
void connection_table_abandon_all_operations(Connection_Table *ct);
|
||||
+void connection_table_disconnect_all(Connection_Table *ct);
|
||||
Connection *connection_table_get_connection(Connection_Table *ct, int sd);
|
||||
int connection_table_move_connection_out_of_active_list(Connection_Table *ct, Connection *c);
|
||||
void connection_table_move_connection_on_to_active_list(Connection_Table *ct, Connection *c);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 830944f72..08754d8fb 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1644,6 +1644,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 */
|
||||
int c_ns_close_jobs; /* number of current close jobs */
|
||||
char *c_ipaddr; /* ip address str - used by monitor */
|
||||
} Connection;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,239 +0,0 @@
|
|||
From 8d79d7c81157e77f4da595a723a6ed10a8e9789b Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Thu, 11 Jan 2018 18:52:43 +0100
|
||||
Subject: [PATCH] Ticket 49509 - Indexing of internationalized matching rules
|
||||
is failing
|
||||
|
||||
Bug Description:
|
||||
Indexing of the internationalized matching rules tests if a
|
||||
matching rule indexer handle or not a given OID.
|
||||
A side effect of https://pagure.io/389-ds-base/issue/49097 is that
|
||||
the returned indexing callbacks are lost.
|
||||
Indeed, the indexing callbacks (and potentially others fields) were
|
||||
stored in the temporary pblock that was memcpy to the provided
|
||||
pblock in case of success
|
||||
|
||||
Fix Description:
|
||||
The fix basically restores the previous behavior but do not
|
||||
memcpy pblock. It read/store the pblock fields that are
|
||||
inputs/outputs of slapi_mr_indexer_create.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49509
|
||||
|
||||
Reviewed by: Ludwig Krispenz
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/plugin_mr.c | 148 ++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 103 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
|
||||
index bd2baff6c..ca4fe00e1 100644
|
||||
--- a/ldap/servers/slapd/plugin_mr.c
|
||||
+++ b/ldap/servers/slapd/plugin_mr.c
|
||||
@@ -143,6 +143,82 @@ plugin_mr_bind(char *oid, struct slapdplugin *plugin)
|
||||
slapi_log_err(SLAPI_LOG_FILTER, "plugin_mr_bind", "<=\n");
|
||||
}
|
||||
|
||||
+void
|
||||
+mr_indexer_init_pb(Slapi_PBlock* src_pb, Slapi_PBlock* dst_pb)
|
||||
+{
|
||||
+ char* oid;
|
||||
+ char *type;
|
||||
+ uint32_t usage;
|
||||
+ void *object;
|
||||
+ IFP destroyFn;
|
||||
+ IFP indexFn, indexSvFn;
|
||||
+
|
||||
+ /* matching rule plugin arguments */
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_OID, &oid);
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_TYPE, &type);
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
+
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_OID, oid);
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_TYPE, type);
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
+
|
||||
+ /* matching rule plugin functions */
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
||||
+
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn);
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn);
|
||||
+
|
||||
+ /* common */
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_OBJECT, &object);
|
||||
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_DESTROY_FN, &destroyFn);
|
||||
+
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_OBJECT, object);
|
||||
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_DESTROY_FN, destroyFn);
|
||||
+
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Retrieves the matching rule plugin able to index/sort the provided OID/type
|
||||
+ *
|
||||
+ * The Matching rules able to index/sort a given OID are stored in a global list: global_mr_oids
|
||||
+ *
|
||||
+ * The retrieval is done in 3 phases:
|
||||
+ * - It first searches (in global_mr_oids) for the already bound OID->MR
|
||||
+ * - Else, look first in old style MR plugin
|
||||
+ * for each registered 'syntax' and 'matchingrule' plugins having a
|
||||
+ * SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, it binds (plugin_mr_bind) the first
|
||||
+ * plugin that support the OID
|
||||
+ * - Else, look in new style MR plugin
|
||||
+ * for each registered 'syntax' and 'matchingrule' plugins, it binds (plugin_mr_bind) the first
|
||||
+ * plugin that contains OID in its plg_mr_names
|
||||
+ *
|
||||
+ * Inputs:
|
||||
+ * SLAPI_PLUGIN_MR_OID
|
||||
+ * should contain the OID of the matching rule that you want used for indexing or sorting.
|
||||
+ * SLAPI_PLUGIN_MR_TYPE
|
||||
+ * should contain the attribute type that you want used for indexing or sorting.
|
||||
+ * SLAPI_PLUGIN_MR_USAGE
|
||||
+ * should specify if the indexer will be used for indexing (SLAPI_PLUGIN_MR_USAGE_INDEX)
|
||||
+ * or for sorting (SLAPI_PLUGIN_MR_USAGE_SORT)
|
||||
+ *
|
||||
+ *
|
||||
+ * Output:
|
||||
+ *
|
||||
+ * SLAPI_PLUGIN_MR_OID
|
||||
+ * contain the OFFICIAL OID of the matching rule that you want used for indexing or sorting.
|
||||
+ * SLAPI_PLUGIN_MR_INDEX_FN
|
||||
+ * specifies the indexer function responsible for indexing or sorting of struct berval **
|
||||
+ * SLAPI_PLUGIN_MR_INDEX_SV_FN
|
||||
+ * specifies the indexer function responsible for indexing or sorting of Slapi_Value **
|
||||
+ * SLAPI_PLUGIN_OBJECT
|
||||
+ * contain any information that you want passed to the indexer function.
|
||||
+ * SLAPI_PLUGIN_DESTROY_FN
|
||||
+ * specifies the function responsible for freeing any memory allocated by this indexer factory function.
|
||||
+ * For example, memory allocated for a structure that you pass to the indexer function using SLAPI_PLUGIN_OBJECT.
|
||||
+ *
|
||||
+ */
|
||||
int /* an LDAP error code, hopefully LDAP_SUCCESS */
|
||||
slapi_mr_indexer_create(Slapi_PBlock *opb)
|
||||
{
|
||||
@@ -152,28 +228,33 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
|
||||
IFP createFn = NULL;
|
||||
struct slapdplugin *mrp = plugin_mr_find_registered(oid);
|
||||
if (mrp != NULL) {
|
||||
+ /* Great the matching OID -> MR plugin was already found, just reuse it */
|
||||
if (!(rc = slapi_pblock_set(opb, SLAPI_PLUGIN, mrp)) &&
|
||||
!(rc = slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
|
||||
createFn != NULL) {
|
||||
rc = createFn(opb);
|
||||
}
|
||||
} else {
|
||||
- /* call each plugin, until one is able to handle this request. */
|
||||
+ /* We need to find in the MR plugins list, the MR plugin that will be able to handle OID
|
||||
+ *
|
||||
+ * It can be "old style" MR plugin (i.e. collation) that define indexer
|
||||
+ *
|
||||
+ * It can be "now style" MR plugin that contain OID string in 'plg_mr_names'
|
||||
+ * (ie. ces, cis, bin...) where plg_mr_names is defined in 'mr_plugin_table' in each file
|
||||
+ * ces.c, cis.c...
|
||||
+ * New style MR plugin have NULL indexer create function but rather use a default indexer
|
||||
+ */
|
||||
+
|
||||
+ /* Look for a old syntax-style mr plugin
|
||||
+ * call each plugin, until one is able to handle this request.
|
||||
+ */
|
||||
rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
|
||||
- // We need to get the type and usage from the caller.
|
||||
- char *type;
|
||||
- uint32_t usage;
|
||||
- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_TYPE, &type);
|
||||
- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
+
|
||||
for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) {
|
||||
|
||||
Slapi_PBlock *pb = slapi_pblock_new();
|
||||
+ mr_indexer_init_pb(opb, pb);
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN, mrp);
|
||||
- /* From filtercmp.c and matchrule.c, these are the values we need to set. into pb */
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
-
|
||||
/* This is associated with the pb_plugin struct, so it comes with mrp */
|
||||
if (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) {
|
||||
/* plugin not a matchingrule type */
|
||||
@@ -185,14 +266,11 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
|
||||
IFP indexFn = NULL;
|
||||
IFP indexSvFn = NULL;
|
||||
/* These however, are in the pblock direct, so we need to copy them. */
|
||||
- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
||||
- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn);
|
||||
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
||||
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
||||
if (indexFn || indexSvFn) {
|
||||
/* Success: this plugin can handle it. */
|
||||
- /* call create on the opb? */
|
||||
- createFn(opb);
|
||||
+ mr_indexer_init_pb(pb, opb);
|
||||
plugin_mr_bind(oid, mrp); /* for future reference */
|
||||
rc = 0; /* success */
|
||||
slapi_pblock_destroy(pb);
|
||||
@@ -205,37 +283,12 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
|
||||
/* look for a new syntax-style mr plugin */
|
||||
struct slapdplugin *pi = plugin_mr_find(oid);
|
||||
if (pi) {
|
||||
- Slapi_PBlock *pb = slapi_pblock_new();
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN, pi);
|
||||
- rc = default_mr_indexer_create(pb);
|
||||
+ slapi_pblock_set(opb, SLAPI_PLUGIN, pi);
|
||||
+ rc = default_mr_indexer_create(opb);
|
||||
if (!rc) {
|
||||
- /* On success, copy the needed values in. These are added by default_mr_indexer_create */
|
||||
- void *pb_object = NULL;
|
||||
- IFP destroy_fn = NULL;
|
||||
- IFP index_fn = NULL;
|
||||
- IFP index_sv_fn = NULL;
|
||||
-
|
||||
- slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &pb_object);
|
||||
- slapi_pblock_get(pb, SLAPI_PLUGIN_DESTROY_FN, &destroy_fn);
|
||||
- slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &index_fn);
|
||||
- slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &index_sv_fn);
|
||||
-
|
||||
- /* SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, and SLAPI_PLUGIN_MR_FILTER_CREATE_FN, are part of pb_plugin */
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN, pi);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_OID, oid);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_TYPE, type);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_OBJECT, pb_object);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_DESTROY_FN, destroy_fn);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_FN, index_fn);
|
||||
- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, index_sv_fn);
|
||||
-
|
||||
plugin_mr_bind(oid, pi); /* for future reference */
|
||||
}
|
||||
- slapi_pblock_destroy(pb);
|
||||
+ slapi_pblock_set(opb, SLAPI_PLUGIN, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,6 +759,11 @@ default_mr_indexer_create(Slapi_PBlock *pb)
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn);
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn);
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy);
|
||||
+
|
||||
+ /* Note the two following setting are in the slapdplugin struct SLAPI_PLUGIN
|
||||
+ * so they are not really output of the function but will just
|
||||
+ * be stored in the bound (OID <--> plugin) list (plugin_mr_find_registered/plugin_mr_bind)
|
||||
+ */
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create);
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create);
|
||||
rc = 0;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
From a7a0db402b32dcec7fc93bcbef42174163ae9c12 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Tue, 12 Dec 2017 12:46:37 +0100
|
||||
Subject: [PATCH] Ticket 49493 - heap use after free in csn_as_string
|
||||
|
||||
Bug: If write_changlog_and_ruv failed teh csn pending list was not properly
|
||||
cleand and references to the prim csn were kept, but the prim csn was reset
|
||||
|
||||
Fix: check the return code for the mmr postop plugin and aset error codes properly
|
||||
that will triger cancel_opcsn
|
||||
|
||||
Reviewed by: Thierry, thanks
|
||||
Tested by: Viktor, thanks
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_add.c | 22 +---------------------
|
||||
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 4 ++++
|
||||
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 ++++
|
||||
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 4 ++++
|
||||
ldap/servers/slapd/back-ldbm/misc.c | 18 ++++++++++++++++++
|
||||
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1 +
|
||||
6 files changed, 32 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
index b7e17ad50..f29945a7e 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
@@ -22,7 +22,6 @@ extern char *hassubordinates;
|
||||
|
||||
static void delete_update_entrydn_operational_attributes(struct backentry *ep);
|
||||
|
||||
-static int set_error(Slapi_PBlock *pb, int retval, int ldap_result_code, char **ldap_result_message);
|
||||
#define ADD_SET_ERROR(rc, error, count) \
|
||||
{ \
|
||||
(rc) = (error); \
|
||||
@@ -1201,7 +1200,7 @@ ldbm_back_add(Slapi_PBlock *pb)
|
||||
|
||||
retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_ADD_FN);
|
||||
if (retval) {
|
||||
- set_error(pb, retval, ldap_result_code, &ldap_result_message);
|
||||
+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
@@ -1471,22 +1470,3 @@ delete_update_entrydn_operational_attributes(struct backentry *ep)
|
||||
slapi_entry_attr_delete(ep->ep_entry, LDBM_ENTRYDN_STR);
|
||||
}
|
||||
|
||||
-static int
|
||||
-set_error(Slapi_PBlock *pb, int retval, int ldap_result_code, char **ldap_result_message)
|
||||
-{
|
||||
- int opreturn = 0;
|
||||
- if (!ldap_result_code) {
|
||||
- slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
|
||||
- }
|
||||
- if (!ldap_result_code) {
|
||||
- ldap_result_code = LDAP_OPERATIONS_ERROR;
|
||||
- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
|
||||
- }
|
||||
- slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
|
||||
- if (!opreturn) {
|
||||
- slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
|
||||
- }
|
||||
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
|
||||
-
|
||||
- return opreturn;
|
||||
-}
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
index db463c18c..be0db1bd0 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
@@ -1276,6 +1276,10 @@ replace_entry:
|
||||
}
|
||||
|
||||
retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN);
|
||||
+ if (retval) {
|
||||
+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message);
|
||||
+ goto error_return;
|
||||
+ }
|
||||
|
||||
commit_return:
|
||||
/* Release SERIAL LOCK */
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
||||
index 7ee796fd2..cc4319e5f 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
||||
@@ -867,6 +867,10 @@ ldbm_back_modify(Slapi_PBlock *pb)
|
||||
goto error_return;
|
||||
}
|
||||
retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN);
|
||||
+ if (retval) {
|
||||
+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message);
|
||||
+ goto error_return;
|
||||
+ }
|
||||
|
||||
/* Release SERIAL LOCK */
|
||||
retval = dblayer_txn_commit(be, &txn);
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||
index 2c0cb074e..93fb77dc9 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
||||
@@ -1211,6 +1211,10 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
|
||||
goto error_return;
|
||||
}
|
||||
retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN);
|
||||
+ if (retval) {
|
||||
+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message);
|
||||
+ goto error_return;
|
||||
+ }
|
||||
|
||||
/* Release SERIAL LOCK */
|
||||
retval = dblayer_txn_commit(be, &txn);
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
|
||||
index df1afdfb1..c52e58a4a 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/misc.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/misc.c
|
||||
@@ -16,6 +16,24 @@
|
||||
|
||||
#include "back-ldbm.h"
|
||||
|
||||
+void
|
||||
+ldbm_set_error(Slapi_PBlock *pb, int retval, int *ldap_result_code, char **ldap_result_message)
|
||||
+{
|
||||
+ int opreturn = 0;
|
||||
+ if (!(*ldap_result_code)) {
|
||||
+ slapi_pblock_get(pb, SLAPI_RESULT_CODE, ldap_result_code);
|
||||
+ }
|
||||
+ if (!(*ldap_result_code)) {
|
||||
+ *ldap_result_code = LDAP_OPERATIONS_ERROR;
|
||||
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, ldap_result_code);
|
||||
+ }
|
||||
+ slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
|
||||
+ if (!opreturn) {
|
||||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, *ldap_result_code ? ldap_result_code : &retval);
|
||||
+ }
|
||||
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message);
|
||||
+}
|
||||
+
|
||||
/* Takes a return code supposed to be errno or from lidb
|
||||
which we don't expect to see and prints a handy log message */
|
||||
void
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
||||
index 0cee3df62..da3eef18b 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
||||
@@ -379,6 +379,7 @@ int ldbm_txn_ruv_modify_context(Slapi_PBlock *pb, modify_context *mc);
|
||||
int get_value_from_string(const char *string, char *type, char **value);
|
||||
int get_values_from_string(const char *string, char *type, char ***valuearray);
|
||||
void normalize_dir(char *dir);
|
||||
+void ldbm_set_error(Slapi_PBlock *pb, int retval, int *ldap_result_code, char **ldap_result_message);
|
||||
|
||||
/*
|
||||
* nextid.c
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
From a85f64d2c4fa2718748a205d4ae0ebab47513199 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 8 Jan 2018 11:34:02 -0500
|
||||
Subject: [PATCH] Ticket 49524 - Password policy: minimum token length fails
|
||||
when the token length is equal to attribute length
|
||||
|
||||
Bug Description: The token checking breaks when the password is the
|
||||
exact value of the entry attribute.
|
||||
|
||||
Fix Description: Remove the "equal" part of the string comparisons.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49524
|
||||
|
||||
Reviewed by: firstyear & spichugi(Thanks!!)
|
||||
|
||||
(cherry picked from commit 790be09fc434d394239bf2486d01f212b36cf0e3)
|
||||
---
|
||||
.../tests/suites/password/pwdPolicy_token_test.py | 75 ++++++++++++++++++++++
|
||||
ldap/servers/slapd/pw.c | 2 +-
|
||||
ldap/servers/slapd/utf8.c | 2 +-
|
||||
3 files changed, 77 insertions(+), 2 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
|
||||
new file mode 100644
|
||||
index 000000000..7a4de9c85
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py
|
||||
@@ -0,0 +1,75 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import time
|
||||
+import ldap
|
||||
+from lib389._constants import *
|
||||
+from lib389.idm.user import UserAccounts
|
||||
+from lib389.topologies import topology_st 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__)
|
||||
+
|
||||
+USER_DN = 'uid=Test_user1,ou=People,dc=example,dc=com'
|
||||
+TOKEN = 'test_user1'
|
||||
+
|
||||
+user_properties = {
|
||||
+ 'uid': 'Test_user1',
|
||||
+ 'cn': 'test_user1',
|
||||
+ 'sn': 'test_user1',
|
||||
+ 'uidNumber': '1001',
|
||||
+ 'gidNumber': '2001',
|
||||
+ 'userpassword': PASSWORD,
|
||||
+ 'description': 'userdesc',
|
||||
+ 'homeDirectory': '/home/{}'.format('test_user')}
|
||||
+
|
||||
+
|
||||
+def pwd_setup(topo):
|
||||
+ topo.standalone.config.replace_many(('passwordCheckSyntax', 'on'),
|
||||
+ ('passwordMinLength', '4'),
|
||||
+ ('passwordMinCategories', '1'))
|
||||
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
|
||||
+ return users.create(properties=user_properties)
|
||||
+
|
||||
+
|
||||
+def test_token_lengths(topo):
|
||||
+ """Test that password token length is enforced for various lengths including
|
||||
+ the same length as the attribute being checked by the policy.
|
||||
+
|
||||
+ :id: dae9d916-2a03-4707-b454-9e901d295b13
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1. Test token length rejects password of the same length as rdn value
|
||||
+ :expectedresults:
|
||||
+ 1. Passwords are rejected
|
||||
+ """
|
||||
+ user = pwd_setup(topo)
|
||||
+ for length in ['4', '6', '10']:
|
||||
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ topo.standalone.config.set('passwordMinTokenLength', length)
|
||||
+ topo.standalone.simple_bind_s(USER_DN, PASSWORD)
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ try:
|
||||
+ passwd = TOKEN[:int(length)]
|
||||
+ log.info("Testing password len {} token ({})".format(length, passwd))
|
||||
+ user.replace('userpassword', passwd)
|
||||
+ log.fatal('Password incorrectly allowed!')
|
||||
+ assert False
|
||||
+ except ldap.CONSTRAINT_VIOLATION as e:
|
||||
+ log.info('Password correctly rejected: ' + str(e))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Unexpected failure ' + str(e))
|
||||
+ assert False
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index e625962e8..0cf795b41 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -1465,7 +1465,7 @@ check_trivial_words(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char *
|
||||
sp = slapi_ch_strdup(slapi_value_get_string(valp));
|
||||
ep = sp + strlen(sp);
|
||||
ep = ldap_utf8prevn(sp, ep, toklen);
|
||||
- if (!ep || (sp >= ep)) {
|
||||
+ if (!ep || (sp > ep)) {
|
||||
slapi_ch_free_string(&sp);
|
||||
continue;
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/utf8.c b/ldap/servers/slapd/utf8.c
|
||||
index b0667c636..4538625b3 100644
|
||||
--- a/ldap/servers/slapd/utf8.c
|
||||
+++ b/ldap/servers/slapd/utf8.c
|
||||
@@ -152,7 +152,7 @@ ldap_utf8prevn(char *s, char *from, int n)
|
||||
}
|
||||
for (; n > 0; --n) {
|
||||
prev = ldap_utf8prev(prev);
|
||||
- if ((prev <= s) && (n > 0)) {
|
||||
+ if ((n > 0) && (prev < s)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
From 7fa2f146c80ed64217bb0c1022c99bd1948cdc7c Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Thu, 11 Jan 2018 15:56:21 +0100
|
||||
Subject: [PATCH] Ticket 49446 - cleanallruv should ignore cleaned replica Id
|
||||
in processing changelog if in force mode
|
||||
|
||||
Bug: If the startcsn is calculated based on a cleaned rid, it could be missing from the changelog.
|
||||
|
||||
Fix: In force mode we do not care that the topology gets in sync for the cleaned RID, so we can ignore it
|
||||
in an earlier stage, instead of setting it to precleane only.
|
||||
|
||||
Reviewed by: Thierry, thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica_config.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index e025f34d8..005528a41 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -1688,9 +1688,15 @@ replica_cleanallruv_thread(void *arg)
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
+ * 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()
|
||||
*/
|
||||
- preset_cleaned_rid(data->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);
|
||||
/*
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
From 7cb2e56db2da439c90bbfd35f132a85708942490 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Tue, 14 Nov 2017 11:25:18 +0100
|
||||
Subject: [PATCH] Ticket 49413 - Changelog trimming ignores disabled
|
||||
replica-agreement
|
||||
|
||||
Bug: if a replication agreement is disabled it is not taken into account when
|
||||
changelog trimming determines where to stop.
|
||||
If the agreement is reenabled later replication can fail
|
||||
|
||||
Fix: do not ignore disabled agreements in changelog trimming
|
||||
|
||||
Reviewed by: Thierry, thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index 721013abf..dc2857910 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -4283,12 +4283,10 @@ _cl5GetRUV2Purge2(Object *fileObj, RUV **ruv)
|
||||
while (agmtObj) {
|
||||
agmt = (Repl_Agmt *)object_get_data(agmtObj);
|
||||
PR_ASSERT(agmt);
|
||||
-
|
||||
- if (!agmt_is_enabled(agmt)) {
|
||||
- agmtObj = agmtlist_get_next_agreement_for_replica(r, agmtObj);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
+ /* we need to handle all agreements, also if they are not enabled
|
||||
+ * if they will be later enabled and changes are trimmed
|
||||
+ * replication can fail
|
||||
+ */
|
||||
consRUVObj = agmt_get_consumer_ruv(agmt);
|
||||
if (consRUVObj) {
|
||||
consRUV = (RUV *)object_get_data(consRUVObj);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,330 +0,0 @@
|
|||
From 6e00c3bac13811bc6d94b810b17a59f9428c29f6 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Thu, 11 Jan 2018 15:17:56 +0100
|
||||
Subject: [PATCH] Ticket 49278 - GetEffectiveRights gives false-negative
|
||||
|
||||
Bug: If geteffective rights was issued for an non existing entry the
|
||||
mechanism to genrate a template entry no longer worked and no results were
|
||||
returned.
|
||||
Fix: Improve the handling in itreating the result set, so that template entries (if
|
||||
requested) are genereated and are not applied to existing entries.
|
||||
Also some code cleanup in iterate()
|
||||
Reviewed by: Thierry, thanks
|
||||
---
|
||||
ldap/servers/slapd/opshared.c | 239 ++++++++++++++++++++----------------------
|
||||
1 file changed, 114 insertions(+), 125 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
||||
index 24157120e..46dcf6fba 100644
|
||||
--- a/ldap/servers/slapd/opshared.c
|
||||
+++ b/ldap/servers/slapd/opshared.c
|
||||
@@ -33,6 +33,7 @@ static char *pwpolicy_lock_attrs_all[] = {"passwordRetryCount",
|
||||
static void compute_limits(Slapi_PBlock *pb);
|
||||
static int send_results_ext(Slapi_PBlock *pb, int send_result, int *nentries, int pagesize, unsigned int *pr_stat);
|
||||
static int process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result);
|
||||
+static void send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries);
|
||||
|
||||
int
|
||||
op_shared_is_allowed_attr(const char *attr_name, int replicated_op)
|
||||
@@ -1040,6 +1041,31 @@ process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+static void
|
||||
+send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries)
|
||||
+{
|
||||
+ /*
|
||||
+ * It's a regular entry, or it's a referral and
|
||||
+ * managedsait control is on. In either case, send
|
||||
+ * the entry.
|
||||
+ */
|
||||
+ switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) {
|
||||
+ case 0: /* entry sent ok */
|
||||
+ (*pnentries)++;
|
||||
+ slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
|
||||
+ break;
|
||||
+ case 1: /* entry not sent */
|
||||
+ break;
|
||||
+ case -1: /* connection closed */
|
||||
+ /*
|
||||
+ * mark the operation as abandoned so the backend
|
||||
+ * next entry function gets called again and has
|
||||
+ * a chance to clean things up.
|
||||
+ */
|
||||
+ operation->o_status = SLAPI_OP_STATUS_ABANDONED;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
|
||||
#if 0
|
||||
/* Loops through search entries and sends them to the client.
|
||||
@@ -1214,7 +1240,7 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in
|
||||
*pnentries = 0;
|
||||
|
||||
while (!done) {
|
||||
- Slapi_Entry *gerentry = NULL;
|
||||
+ Slapi_Entry *ger_template_entry = NULL;
|
||||
Slapi_Operation *operation;
|
||||
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
|
||||
@@ -1236,57 +1262,57 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in
|
||||
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
|
||||
|
||||
/* Check for possible get_effective_rights control */
|
||||
- if (e) {
|
||||
- if (operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS) {
|
||||
- char *errbuf = NULL;
|
||||
+ if (operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS) {
|
||||
+ char *errbuf = NULL;
|
||||
+
|
||||
+ if (PAGEDRESULTS_PAGE_END == pr_stat) {
|
||||
+ /*
|
||||
+ * read ahead -- there is at least more entry.
|
||||
+ * undo it and return the PAGE_END
|
||||
+ */
|
||||
+ be->be_prev_search_results(pb);
|
||||
+ done = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if ( e == NULL ) {
|
||||
char **gerattrs = NULL;
|
||||
char **gerattrsdup = NULL;
|
||||
char **gap = NULL;
|
||||
char *gapnext = NULL;
|
||||
-
|
||||
- if (PAGEDRESULTS_PAGE_END == pr_stat) {
|
||||
- /*
|
||||
- * read ahead -- there is at least more entry.
|
||||
- * undo it and return the PAGE_END
|
||||
+ /* we have no more entries
|
||||
+ * but we might create a template entry for GER
|
||||
+ * so we need to continue, but make sure to stop
|
||||
+ * after handling the template entry.
|
||||
+ * the template entry is a temporary entry returned by the acl
|
||||
+ * plugin in the pblock and will be freed
|
||||
*/
|
||||
- be->be_prev_search_results(pb);
|
||||
- done = 1;
|
||||
- continue;
|
||||
- }
|
||||
+ done = 1;
|
||||
+ pr_stat = PAGEDRESULTS_SEARCH_END;
|
||||
|
||||
slapi_pblock_get(pb, SLAPI_SEARCH_GERATTRS, &gerattrs);
|
||||
gerattrsdup = cool_charray_dup(gerattrs);
|
||||
gap = gerattrsdup;
|
||||
- do {
|
||||
+ while (gap && *gap) {
|
||||
gapnext = NULL;
|
||||
- if (gap) {
|
||||
- if (*gap && *(gap + 1)) {
|
||||
- gapnext = *(gap + 1);
|
||||
- *(gap + 1) = NULL;
|
||||
- }
|
||||
- slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap);
|
||||
- rc = plugin_call_acl_plugin(pb, e, attrs, NULL,
|
||||
- SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
|
||||
- &errbuf);
|
||||
- if (NULL != gapnext) {
|
||||
- *(gap + 1) = gapnext;
|
||||
- }
|
||||
- } else if (NULL != e) {
|
||||
- rc = plugin_call_acl_plugin(pb, e, attrs, NULL,
|
||||
- SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
|
||||
- &errbuf);
|
||||
+ if (*(gap + 1)) {
|
||||
+ gapnext = *(gap + 1);
|
||||
+ *(gap + 1) = NULL;
|
||||
+ }
|
||||
+ slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap);
|
||||
+ rc = plugin_call_acl_plugin(pb, e, attrs, NULL,
|
||||
+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
|
||||
+ &errbuf);
|
||||
+ if (NULL != gapnext) {
|
||||
+ *(gap + 1) = gapnext;
|
||||
}
|
||||
+ gap++;
|
||||
+ /* get the template entry, if any */
|
||||
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
|
||||
if (NULL == e) {
|
||||
- /* get the template entry, if any */
|
||||
- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e);
|
||||
- if (NULL == e) {
|
||||
- /* everything is ok - don't send the result */
|
||||
- pr_stat = PAGEDRESULTS_SEARCH_END;
|
||||
- done = 1;
|
||||
- continue;
|
||||
- }
|
||||
- gerentry = e;
|
||||
+ /* everything is ok - don't send the result */
|
||||
+ continue;
|
||||
}
|
||||
+ ger_template_entry = e;
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
/* Send error result and
|
||||
abort op if the control is critical */
|
||||
@@ -1294,65 +1320,53 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in
|
||||
"Failed to get effective rights for entry (%s), rc=%d\n",
|
||||
slapi_entry_get_dn_const(e), rc);
|
||||
send_ldap_result(pb, rc, NULL, errbuf, 0, NULL);
|
||||
- slapi_ch_free((void **)&errbuf);
|
||||
- if (gerentry) {
|
||||
- slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL);
|
||||
- slapi_entry_free(gerentry);
|
||||
- gerentry = e = NULL;
|
||||
- }
|
||||
- pr_stat = PAGEDRESULTS_SEARCH_END;
|
||||
rval = -1;
|
||||
- done = 1;
|
||||
- continue;
|
||||
- }
|
||||
- slapi_ch_free((void **)&errbuf);
|
||||
- if (process_entry(pb, e, send_result)) {
|
||||
- /* shouldn't send this entry */
|
||||
- if (gerentry) {
|
||||
- slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL);
|
||||
- slapi_entry_free(gerentry);
|
||||
- gerentry = e = NULL;
|
||||
+ } else {
|
||||
+ if (!process_entry(pb, e, send_result)) {
|
||||
+ /* should send this entry now*/
|
||||
+ send_entry(pb, e, operation, attrs, attrsonly, pnentries);
|
||||
}
|
||||
- continue;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * It's a regular entry, or it's a referral and
|
||||
- * managedsait control is on. In either case, send
|
||||
- * the entry.
|
||||
- */
|
||||
- switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) {
|
||||
- case 0: /* entry sent ok */
|
||||
- (*pnentries)++;
|
||||
- slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
|
||||
- break;
|
||||
- case 1: /* entry not sent */
|
||||
- break;
|
||||
- case -1: /* connection closed */
|
||||
- /*
|
||||
- * mark the operation as abandoned so the backend
|
||||
- * next entry function gets called again and has
|
||||
- * a chance to clean things up.
|
||||
- */
|
||||
- operation->o_status = SLAPI_OP_STATUS_ABANDONED;
|
||||
- break;
|
||||
- }
|
||||
- if (gerentry) {
|
||||
+ slapi_ch_free((void **)&errbuf);
|
||||
+ if (ger_template_entry) {
|
||||
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL);
|
||||
- slapi_entry_free(gerentry);
|
||||
- gerentry = e = NULL;
|
||||
+ slapi_entry_free(ger_template_entry);
|
||||
+ ger_template_entry = e = NULL;
|
||||
}
|
||||
- } while (gap && ++gap && *gap);
|
||||
+ } /* while ger template */
|
||||
slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gerattrs);
|
||||
cool_charray_free(gerattrsdup);
|
||||
- if (pagesize == *pnentries) {
|
||||
- /* PAGED RESULTS: reached the pagesize */
|
||||
- /* We don't set "done = 1" here.
|
||||
- * We read ahead next entry to check whether there is
|
||||
- * more entries to return or not. */
|
||||
- pr_stat = PAGEDRESULTS_PAGE_END;
|
||||
+ } else {
|
||||
+ /* we are processing geteffective rights for an existing entry */
|
||||
+ rc = plugin_call_acl_plugin(pb, e, attrs, NULL,
|
||||
+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS,
|
||||
+ &errbuf);
|
||||
+ if (rc != LDAP_SUCCESS) {
|
||||
+ /* Send error result and
|
||||
+ abort op if the control is critical */
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "iterate",
|
||||
+ "Failed to get effective rights for entry (%s), rc=%d\n",
|
||||
+ slapi_entry_get_dn_const(e), rc);
|
||||
+ send_ldap_result(pb, rc, NULL, errbuf, 0, NULL);
|
||||
+ rval = -1;
|
||||
+ } else {
|
||||
+ if (!process_entry(pb, e, send_result)) {
|
||||
+ /* should send this entry now*/
|
||||
+ send_entry(pb, e, operation, attrs, attrsonly, pnentries);
|
||||
+ if (pagesize == *pnentries) {
|
||||
+ /* PAGED RESULTS: reached the pagesize */
|
||||
+ /* We don't set "done = 1" here.
|
||||
+ * We read ahead next entry to check whether there is
|
||||
+ * more entries to return or not. */
|
||||
+ pr_stat = PAGEDRESULTS_PAGE_END;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- } else { /* not GET_EFFECTIVE_RIGHTS */
|
||||
+ slapi_ch_free((void **)&errbuf);
|
||||
+ }
|
||||
+ /* not GET_EFFECTIVE_RIGHTS */
|
||||
+ } else if (e) {
|
||||
if (PAGEDRESULTS_PAGE_END == pr_stat) {
|
||||
/*
|
||||
* read ahead -- there is at least more entry.
|
||||
@@ -1364,46 +1378,21 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in
|
||||
}
|
||||
/* Adding shadow password attrs. */
|
||||
add_shadow_ext_password_attrs(pb, &e);
|
||||
- if (process_entry(pb, e, send_result)) {
|
||||
- /* shouldn't send this entry */
|
||||
- struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb);
|
||||
- slapi_entry_free(pb_pw_entry);
|
||||
- slapi_pblock_set_pw_entry(pb, NULL);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * It's a regular entry, or it's a referral and
|
||||
- * managedsait control is on. In either case, send
|
||||
- * the entry.
|
||||
- */
|
||||
- switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) {
|
||||
- case 0: /* entry sent ok */
|
||||
- (*pnentries)++;
|
||||
- slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries);
|
||||
- break;
|
||||
- case 1: /* entry not sent */
|
||||
- break;
|
||||
- case -1: /* connection closed */
|
||||
- /*
|
||||
- * mark the operation as abandoned so the backend
|
||||
- * next entry function gets called again and has
|
||||
- * a chance to clean things up.
|
||||
- */
|
||||
- operation->o_status = SLAPI_OP_STATUS_ABANDONED;
|
||||
- break;
|
||||
+ if (!process_entry(pb, e, send_result)) {
|
||||
+ /*this entry was not sent, do it now*/
|
||||
+ send_entry(pb, e, operation, attrs, attrsonly, pnentries);
|
||||
+ if (pagesize == *pnentries) {
|
||||
+ /* PAGED RESULTS: reached the pagesize */
|
||||
+ /* We don't set "done = 1" here.
|
||||
+ * We read ahead next entry to check whether there is
|
||||
+ * more entries to return or not. */
|
||||
+ pr_stat = PAGEDRESULTS_PAGE_END;
|
||||
+ }
|
||||
}
|
||||
+ /* cleanup pw entry . sent or not */
|
||||
struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb);
|
||||
slapi_entry_free(pb_pw_entry);
|
||||
slapi_pblock_set_pw_entry(pb, NULL);
|
||||
- if (pagesize == *pnentries) {
|
||||
- /* PAGED RESULTS: reached the pagesize */
|
||||
- /* We don't set "done = 1" here.
|
||||
- * We read ahead next entry to check whether there is
|
||||
- * more entries to return or not. */
|
||||
- pr_stat = PAGEDRESULTS_PAGE_END;
|
||||
- }
|
||||
- }
|
||||
} else {
|
||||
/* no more entries */
|
||||
done = 1;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From 7acfb18228322ab2e331720bd7fe083da04625a2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 12 Jan 2018 09:50:34 -0500
|
||||
Subject: [PATCH] Ticket 49531 - coverity issues - fix memory leaks
|
||||
|
||||
Description: There were two false positives around pwpolicy struct
|
||||
being leaked, but it is freed when the pblock is
|
||||
destroyed. The other two leaks were real, but they
|
||||
only occurred during error conditions.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49531
|
||||
|
||||
Reviewed by: lkrispen (Thanks!)
|
||||
|
||||
(cherry picked from commit 700d7422e6309d2d405961abbb805fbfe852e53c)
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 1 +
|
||||
ldap/servers/plugins/replication/urp.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index dc2857910..89ae9956c 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -4046,6 +4046,7 @@ _cl5WriteRUV(CL5DBFile *file, PRBool purge)
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
|
||||
"_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n",
|
||||
file->name);
|
||||
+ ber_bvecfree(vals);
|
||||
return CL5_DB_ERROR;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c
|
||||
index 9534c0322..d4556d7fd 100644
|
||||
--- a/ldap/servers/plugins/replication/urp.c
|
||||
+++ b/ldap/servers/plugins/replication/urp.c
|
||||
@@ -861,7 +861,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
Slapi_Entry *pre_entry = NULL;
|
||||
int ret = 0;
|
||||
Slapi_DN *pre_sdn = NULL;
|
||||
- Slapi_RDN *rdn = slapi_rdn_new();
|
||||
+ Slapi_RDN *rdn = NULL;
|
||||
char *parentdn = NULL;
|
||||
char *newdn;
|
||||
const char *entrydn;
|
||||
@@ -882,6 +882,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
entrydn = slapi_entry_get_ndn (pre_entry);*/
|
||||
uniqueid = slapi_entry_get_uniqueid (pre_entry);
|
||||
parentdn = slapi_dn_parent(entrydn);
|
||||
+ rdn = slapi_rdn_new();
|
||||
slapi_sdn_get_rdn(pre_sdn, rdn);
|
||||
slapi_rdn_remove_attr (rdn, SLAPI_ATTR_UNIQUEID );
|
||||
slapi_rdn_add(rdn, "cenotaphID", uniqueid);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,503 +0,0 @@
|
|||
From 0b5cbcf45f3fb4b03a1f762c5704183787d30696 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 12 Jan 2018 08:38:22 -0500
|
||||
Subject: [PATCH] Ticket 49529 - Fix Coverity warnings: invalid deferences
|
||||
|
||||
Description: So many of the warnings were false positives, but
|
||||
I "fixed" 90% of them anyway for these two reasons:
|
||||
|
||||
One, it's possible that a future change could actually
|
||||
result in a NULL pointer being referenced.
|
||||
|
||||
Two, it would be nice to stop these coverity warnings
|
||||
so we can focus on real warnings. Auto waivers also
|
||||
don't always work as the surrounding code changes.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49529
|
||||
|
||||
Reviewed by: firstyear (Thanks!)
|
||||
|
||||
(cherry picked from commit 7e27face5ef021d883a44d70bb3e9732b115016f)
|
||||
---
|
||||
ldap/servers/slapd/abandon.c | 10 ++++++++--
|
||||
ldap/servers/slapd/add.c | 18 +++++++++++++++---
|
||||
ldap/servers/slapd/bind.c | 20 +++++++++++++++-----
|
||||
ldap/servers/slapd/compare.c | 17 +++++++++++++----
|
||||
ldap/servers/slapd/connection.c | 19 +++++++++++++------
|
||||
ldap/servers/slapd/delete.c | 4 ++--
|
||||
ldap/servers/slapd/dn.c | 7 +++++++
|
||||
ldap/servers/slapd/entry.c | 10 +++++++++-
|
||||
ldap/servers/slapd/extendop.c | 7 +++++++
|
||||
ldap/servers/slapd/filter.c | 6 +++++-
|
||||
ldap/servers/slapd/modify.c | 18 ++++++++++++++++--
|
||||
ldap/servers/slapd/passwd_extop.c | 4 ++++
|
||||
ldap/servers/slapd/psearch.c | 13 +++++++++----
|
||||
ldap/servers/slapd/result.c | 14 +++++++++++++-
|
||||
ldap/servers/slapd/search.c | 5 ++++-
|
||||
ldap/servers/slapd/task.c | 5 +++++
|
||||
16 files changed, 145 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c
|
||||
index 5c30c972d..e2237e5fc 100644
|
||||
--- a/ldap/servers/slapd/abandon.c
|
||||
+++ b/ldap/servers/slapd/abandon.c
|
||||
@@ -42,10 +42,16 @@ do_abandon(Slapi_PBlock *pb)
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
|
||||
- BerElement *ber = pb_op->o_ber;
|
||||
-
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "do_abandon", "->\n");
|
||||
|
||||
+ if (pb_op == NULL || pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_abandon", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n",
|
||||
+ pb_conn, pb_op);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ BerElement *ber = pb_op->o_ber;
|
||||
+
|
||||
/*
|
||||
* Parse the abandon request. It looks like this:
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
|
||||
index 0a4a5d7b2..8f2fdeac8 100644
|
||||
--- a/ldap/servers/slapd/add.c
|
||||
+++ b/ldap/servers/slapd/add.c
|
||||
@@ -66,6 +66,14 @@ do_add(Slapi_PBlock *pb)
|
||||
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
|
||||
+
|
||||
+
|
||||
+ if (operation == NULL || pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_add", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n",
|
||||
+ pb_conn, operation);
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL);
|
||||
+ return;
|
||||
+ }
|
||||
ber = operation->o_ber;
|
||||
|
||||
/* count the add request */
|
||||
@@ -450,8 +458,8 @@ op_shared_add(Slapi_PBlock *pb)
|
||||
|
||||
if (!internal_op) {
|
||||
slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ADD dn=\"%s\"%s\n",
|
||||
- pb_conn->c_connid,
|
||||
- operation->o_opid,
|
||||
+ pb_conn ? pb_conn->c_connid : -1,
|
||||
+ operation ? operation->o_opid: -1,
|
||||
slapi_entry_get_dn_const(e),
|
||||
proxystr ? proxystr : "");
|
||||
} else {
|
||||
@@ -865,7 +873,11 @@ handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry)
|
||||
int ret;
|
||||
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
-
|
||||
+ if (pb_conn == NULL){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "handle_fast_add", "NULL param: pb_conn (0x%p)\n", pb_conn);
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL);
|
||||
+ return;
|
||||
+ }
|
||||
be = pb_conn->c_bi_backend;
|
||||
|
||||
if ((be == NULL) || (be->be_wire_import == NULL)) {
|
||||
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
||||
index 4a8e4deaf..a34a21a77 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -54,11 +54,7 @@ do_bind(Slapi_PBlock *pb)
|
||||
{
|
||||
Operation *pb_op = NULL;
|
||||
Connection *pb_conn = NULL;
|
||||
-
|
||||
- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
-
|
||||
- BerElement *ber = pb_op->o_ber;
|
||||
+ BerElement *ber;
|
||||
int err, isroot;
|
||||
ber_tag_t method = LBER_DEFAULT;
|
||||
ber_int_t version = -1;
|
||||
@@ -83,6 +79,16 @@ do_bind(Slapi_PBlock *pb)
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "do_bind", "=>\n");
|
||||
|
||||
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+ if (pb_op == NULL || pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_bind", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n",
|
||||
+ pb_conn, pb_op);
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL);
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
+ ber = pb_op->o_ber;
|
||||
+
|
||||
/*
|
||||
* Parse the bind request. It looks like this:
|
||||
*
|
||||
@@ -856,6 +862,10 @@ log_bind_access(
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
|
||||
+ if (pb_op == NULL || pb_conn == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (method == LDAP_AUTH_SASL && saslmech && msg) {
|
||||
slapi_log_access(LDAP_DEBUG_STATS,
|
||||
"conn=%" PRIu64 " op=%d BIND dn=\"%s\" "
|
||||
diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c
|
||||
index 9bc6b693a..2626d91d0 100644
|
||||
--- a/ldap/servers/slapd/compare.c
|
||||
+++ b/ldap/servers/slapd/compare.c
|
||||
@@ -35,10 +35,7 @@ do_compare(Slapi_PBlock *pb)
|
||||
{
|
||||
Operation *pb_op = NULL;
|
||||
Connection *pb_conn = NULL;
|
||||
- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
-
|
||||
- BerElement *ber = pb_op->o_ber;
|
||||
+ BerElement *ber;
|
||||
char *rawdn = NULL;
|
||||
const char *dn = NULL;
|
||||
struct ava ava = {0};
|
||||
@@ -50,6 +47,18 @@ do_compare(Slapi_PBlock *pb)
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "do_compare", "=>\n");
|
||||
|
||||
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+
|
||||
+ if (pb_op == NULL || pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_compare", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n",
|
||||
+ pb_conn, pb_op);
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL);
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
+
|
||||
+ ber = pb_op->o_ber;
|
||||
+
|
||||
/* count the compare request */
|
||||
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps);
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 8ef115691..fa24ec040 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -1518,7 +1518,7 @@ connection_threadmain()
|
||||
}
|
||||
|
||||
if (!thread_turbo_flag && !more_data) {
|
||||
- Connection *pb_conn = NULL;
|
||||
+ Connection *pb_conn = NULL;
|
||||
|
||||
/* If more data is left from the previous connection_read_operation,
|
||||
we should finish the op now. Client might be thinking it's
|
||||
@@ -1530,6 +1530,13 @@ connection_threadmain()
|
||||
* Connection wait for new work provides the conn and op for us.
|
||||
*/
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+ if (pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain",
|
||||
+ "pb_conn is NULL\n");
|
||||
+ slapi_pblock_destroy(pb);
|
||||
+ g_decr_active_threadcnt();
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
switch (ret) {
|
||||
case CONN_NOWORK:
|
||||
@@ -1702,11 +1709,11 @@ connection_threadmain()
|
||||
* so need locking from here on */
|
||||
signal_listner();
|
||||
/* with nunc-stans, I see an enormous amount of time spent in the poll() in
|
||||
- * connection_read_operation() when the below code is enabled - not sure why
|
||||
- * nunc-stans makes such a huge difference - for now, just disable this code
|
||||
- * when using nunc-stans - it is supposed to be an optimization but turns out
|
||||
- * to not be the opposite with nunc-stans
|
||||
- */
|
||||
+ * connection_read_operation() when the below code is enabled - not sure why
|
||||
+ * nunc-stans makes such a huge difference - for now, just disable this code
|
||||
+ * when using nunc-stans - it is supposed to be an optimization but turns out
|
||||
+ * to not be the opposite with nunc-stans
|
||||
+ */
|
||||
} else if (!enable_nunc_stans) { /* more data in conn - just put back on work_q - bypass poll */
|
||||
bypasspollcnt++;
|
||||
PR_EnterMonitor(conn->c_mutex);
|
||||
diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c
|
||||
index ba238b18f..49cdab138 100644
|
||||
--- a/ldap/servers/slapd/delete.c
|
||||
+++ b/ldap/servers/slapd/delete.c
|
||||
@@ -262,8 +262,8 @@ op_shared_delete(Slapi_PBlock *pb)
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d DEL dn=\"%s\"%s\n",
|
||||
- pb_conn->c_connid,
|
||||
- pb_op->o_opid,
|
||||
+ pb_conn ? pb_conn->c_connid : -1,
|
||||
+ pb_op ? pb_op->o_opid : -1,
|
||||
slapi_sdn_get_dn(sdn),
|
||||
proxystr ? proxystr : "");
|
||||
} else {
|
||||
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
|
||||
index afca37214..abc155533 100644
|
||||
--- a/ldap/servers/slapd/dn.c
|
||||
+++ b/ldap/servers/slapd/dn.c
|
||||
@@ -2477,6 +2477,13 @@ slapi_sdn_copy(const Slapi_DN *from, Slapi_DN *to)
|
||||
{
|
||||
SDN_DUMP(from, "slapi_sdn_copy from");
|
||||
SDN_DUMP(to, "slapi_sdn_copy to");
|
||||
+
|
||||
+ if (to == NULL || from == NULL){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "slapi_sdn_copy",
|
||||
+ "NULL param: from (0x%p) to (0x%p)\n", from, to);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
slapi_sdn_done(to);
|
||||
if (from->udn) {
|
||||
to->flag = slapi_setbit_uchar(to->flag, FLAG_UDN);
|
||||
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
|
||||
index fbbc8faa0..32828b4e2 100644
|
||||
--- a/ldap/servers/slapd/entry.c
|
||||
+++ b/ldap/servers/slapd/entry.c
|
||||
@@ -1998,6 +1998,10 @@ slapi_entry_dup(const Slapi_Entry *e)
|
||||
struct attrs_in_extension *aiep;
|
||||
|
||||
PR_ASSERT(NULL != e);
|
||||
+ if (e == NULL){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "slapi_entry_dup", "entry is NULL\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
ec = slapi_entry_alloc();
|
||||
|
||||
@@ -3660,7 +3664,11 @@ delete_values_sv_internal(
|
||||
Slapi_Attr *a;
|
||||
int retVal = LDAP_SUCCESS;
|
||||
|
||||
-/*
|
||||
+ if (e == NULL){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "delete_values_sv_internal", "entry is NULL\n");
|
||||
+ return LDAP_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ /*
|
||||
* If type is in the protected_attrs_all list, we could ignore the failure,
|
||||
* as the attribute could only exist in the entry in the memory when the
|
||||
* add/mod operation is done, while the retried entry from the db does not
|
||||
diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c
|
||||
index 1594a8c9c..815949be6 100644
|
||||
--- a/ldap/servers/slapd/extendop.c
|
||||
+++ b/ldap/servers/slapd/extendop.c
|
||||
@@ -219,6 +219,13 @@ do_extended(Slapi_PBlock *pb)
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
|
||||
+ if (pb_conn == NULL || pb_op == NULL) {
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_extended",
|
||||
+ "NULL param error: conn (0x%p) op (0x%p)\n", pb_conn, pb_op);
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Parse the extended request. It looks like this:
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/filter.c b/ldap/servers/slapd/filter.c
|
||||
index fe3525f34..ef975e679 100644
|
||||
--- a/ldap/servers/slapd/filter.c
|
||||
+++ b/ldap/servers/slapd/filter.c
|
||||
@@ -292,7 +292,11 @@ get_filter_internal(Connection *conn, BerElement *ber, struct slapi_filter **fil
|
||||
|
||||
case LDAP_FILTER_EXTENDED:
|
||||
slapi_log_err(SLAPI_LOG_FILTER, "get_filter_internal", "EXTENDED\n");
|
||||
- if (conn->c_ldapversion < 3) {
|
||||
+ if (conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "get_filter_internal",
|
||||
+ "NULL param: conn (0x%p)\n", conn);
|
||||
+ err = LDAP_OPERATIONS_ERROR;
|
||||
+ } else if (conn->c_ldapversion < 3) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, "get_filter_internal",
|
||||
"Extensible filter received from v2 client\n");
|
||||
err = LDAP_PROTOCOL_ERROR;
|
||||
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
|
||||
index 0dcac646b..10d263159 100644
|
||||
--- a/ldap/servers/slapd/modify.c
|
||||
+++ b/ldap/servers/slapd/modify.c
|
||||
@@ -122,9 +122,16 @@ do_modify(Slapi_PBlock *pb)
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "do_modify", "=>\n");
|
||||
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
|
||||
- ber = operation->o_ber;
|
||||
-
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+ if (operation == NULL) {
|
||||
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR,
|
||||
+ NULL, "operation is NULL parameter", 0, NULL);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_modify",
|
||||
+ "NULL param: pb_conn (0x%p) operation (0x%p)\n", pb_conn, operation);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ber = operation->o_ber;
|
||||
|
||||
/* count the modify request */
|
||||
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps);
|
||||
@@ -1165,6 +1172,13 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M
|
||||
internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
|
||||
+ if (pb_conn == NULL || operation == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "op_shared_allow_pw_change",
|
||||
+ "NULL param error: conn (0x%p) op (0x%p)\n", pb_conn, operation);
|
||||
+ rc = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
slapi_sdn_init_dn_byref(&sdn, dn);
|
||||
pwpolicy = new_passwdPolicy(pb, (char *)slapi_sdn_get_ndn(&sdn));
|
||||
|
||||
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c
|
||||
index 54a9a6716..40145af2e 100644
|
||||
--- a/ldap/servers/slapd/passwd_extop.c
|
||||
+++ b/ldap/servers/slapd/passwd_extop.c
|
||||
@@ -486,6 +486,10 @@ passwd_modify_extop(Slapi_PBlock *pb)
|
||||
/* Allow password modify only for SSL/TLS established connections and
|
||||
* connections using SASL privacy layers */
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
|
||||
+ if (conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "conn is NULL");
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
if (slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
|
||||
errMesg = "Could not get SASL SSF from connection\n";
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c
|
||||
index e0dd2bf89..1bf062954 100644
|
||||
--- a/ldap/servers/slapd/psearch.c
|
||||
+++ b/ldap/servers/slapd/psearch.c
|
||||
@@ -271,6 +271,11 @@ ps_send_results(void *arg)
|
||||
slapi_pblock_get(ps->ps_pblock, SLAPI_CONNECTION, &pb_conn);
|
||||
slapi_pblock_get(ps->ps_pblock, SLAPI_OPERATION, &pb_op);
|
||||
|
||||
+ if (pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ps_send_results", "pb_conn is NULL\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* need to acquire a reference to this connection so that it will not
|
||||
be released or cleaned up out from under us */
|
||||
PR_EnterMonitor(pb_conn->c_mutex);
|
||||
@@ -280,7 +285,7 @@ ps_send_results(void *arg)
|
||||
if (conn_acq_flag) {
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results",
|
||||
"conn=%" PRIu64 " op=%d Could not acquire the connection - psearch aborted\n",
|
||||
- pb_conn->c_connid, pb_op->o_opid);
|
||||
+ pb_conn->c_connid, pb_op ? pb_op->o_opid : -1);
|
||||
}
|
||||
|
||||
PR_Lock(psearch_list->pl_cvarlock);
|
||||
@@ -290,7 +295,7 @@ ps_send_results(void *arg)
|
||||
if (pb_op == NULL || slapi_op_abandoned(ps->ps_pblock)) {
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results",
|
||||
"conn=%" PRIu64 " op=%d The operation has been abandoned\n",
|
||||
- pb_conn->c_connid, pb_op->o_opid);
|
||||
+ pb_conn->c_connid, pb_op ? pb_op->o_opid : -1);
|
||||
break;
|
||||
}
|
||||
if (NULL == ps->ps_eq_head) {
|
||||
@@ -532,7 +537,7 @@ ps_service_persistent_searches(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chg
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ps_service_persistent_searches",
|
||||
"conn=%" PRIu64 " op=%d entry %s with chgtype %d "
|
||||
"matches the ps changetype %d\n",
|
||||
- pb_conn->c_connid,
|
||||
+ pb_conn ? pb_conn->c_connid : -1,
|
||||
pb_op->o_opid,
|
||||
edn, chgtype, ps->ps_changetypes);
|
||||
|
||||
@@ -609,7 +614,7 @@ ps_service_persistent_searches(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chg
|
||||
/* Turn 'em loose */
|
||||
ps_wakeup_all();
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ps_service_persistent_searches", "Enqueued entry "
|
||||
- "\"%s\" on %d persistent search lists\n",
|
||||
+ "\"%s\" on %d persistent search lists\n",
|
||||
slapi_entry_get_dn_const(e), matched);
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ps_service_persistent_searches",
|
||||
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
||||
index 2302ae96b..ce394d948 100644
|
||||
--- a/ldap/servers/slapd/result.c
|
||||
+++ b/ldap/servers/slapd/result.c
|
||||
@@ -396,7 +396,7 @@ send_ldap_result_ext(
|
||||
break;
|
||||
|
||||
case LDAP_REFERRAL:
|
||||
- if (conn->c_ldapversion > LDAP_VERSION2) {
|
||||
+ if (conn && conn->c_ldapversion > LDAP_VERSION2) {
|
||||
tag = LDAP_TAG_REFERRAL;
|
||||
break;
|
||||
}
|
||||
@@ -645,6 +645,11 @@ process_read_entry_controls(Slapi_PBlock *pb, char *oid)
|
||||
BerElement *req_ber = NULL;
|
||||
Operation *op = NULL;
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
||||
+ if (op == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "process_read_entry_controls", "op is NULL\n");
|
||||
+ rc = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
if (strcmp(oid, LDAP_CONTROL_PRE_READ_ENTRY) == 0) {
|
||||
/* first verify this is the correct operation for a pre-read entry control */
|
||||
@@ -2145,6 +2150,13 @@ encode_read_entry(Slapi_PBlock *pb, Slapi_Entry *e, char **attrs, int alluseratt
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
||||
slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
|
||||
|
||||
+ if (conn == NULL || op == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "encode_read_entry",
|
||||
+ "NULL param error: conn (0x%p) op (0x%p)\n", conn, op);
|
||||
+ rc = -1;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
/* Start the ber encoding with the DN */
|
||||
rc = ber_printf(ber, "t{s{", LDAP_RES_SEARCH_ENTRY, slapi_entry_get_dn_const(e));
|
||||
if (rc == -1) {
|
||||
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
|
||||
index 5e3413245..731c6519e 100644
|
||||
--- a/ldap/servers/slapd/search.c
|
||||
+++ b/ldap/servers/slapd/search.c
|
||||
@@ -125,7 +125,10 @@ do_search(Slapi_PBlock *pb)
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+ if (slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn) != 0 || pb_conn == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "do_search", "pb_conn is NULL\n");
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If nsslapd-minssf-exclude-rootdse is on, the minssf check has been
|
||||
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
|
||||
index 53a0af52d..002083c04 100644
|
||||
--- a/ldap/servers/slapd/task.c
|
||||
+++ b/ldap/servers/slapd/task.c
|
||||
@@ -199,6 +199,11 @@ slapi_task_log_status(Slapi_Task *task, char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
+ if (task == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "slapi_task_log_status",
|
||||
+ "Slapi_Task is NULL, can not log status\n");
|
||||
+ return;
|
||||
+ }
|
||||
if (!task->task_status)
|
||||
task->task_status = (char *)slapi_ch_malloc(10 * LOG_BUFFER);
|
||||
if (!task->task_status)
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,286 +0,0 @@
|
|||
From 0ac68e15a9a4048d3c1ad4519000996cd65fdefb Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 1 Dec 2017 16:23:11 +0100
|
||||
Subject: [PATCH] Ticket 49463 - After cleanALLruv, there is a flow of keep
|
||||
alive DEL
|
||||
|
||||
Bug Description:
|
||||
When cleanAllRuv is launched, it spawn cleanAllRuv on all replicas.
|
||||
Each replica will clean its changelog and database RUV AND in addition
|
||||
will DEL the keep alive entry of the target ReplicaID.
|
||||
So for the same entry (keep alive) there will be as many DEL as there are replicas
|
||||
|
||||
This flow of DEL is useless as only one DEL is enough.
|
||||
In addition because of https://pagure.io/389-ds-base/issue/49466, replication may
|
||||
loop on each of those DELs.
|
||||
|
||||
Fix Description:
|
||||
The fix is only to prevent the flow of DEL.
|
||||
It adds a flag ('original_task') in the task payload.
|
||||
The server receiving the task (replica_execute_cleanall_ruv_task) flags the
|
||||
task as 'original_task'.
|
||||
In the opposite, the propagated cleanAllRuv (multimaster_extop_cleanruv) does
|
||||
not flag the task as 'original_task'
|
||||
Only original task does the DEL of the keep alive entry.
|
||||
Note the propageted payload (extop) is not changed. In a mixed version
|
||||
environment "old" servers will DEL the keep alive and flow can still happen
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49466
|
||||
|
||||
Reviewed by: Ludwig Krispenz
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5.h | 49 ++++++++++++----------
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 21 ++++++++++
|
||||
.../plugins/replication/repl5_replica_config.c | 32 +++++++++++---
|
||||
ldap/servers/plugins/replication/repl_extop.c | 2 +
|
||||
4 files changed, 76 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||
index 4e206a0fc..e08fec752 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||
@@ -783,12 +783,37 @@ 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 */
|
||||
+
|
||||
+typedef struct _cleanruv_data
|
||||
+{
|
||||
+ Object *repl_obj;
|
||||
+ Replica *replica;
|
||||
+ ReplicaId rid;
|
||||
+ Slapi_Task *task;
|
||||
+ struct berval *payload;
|
||||
+ CSN *maxcsn;
|
||||
+ char *repl_root;
|
||||
+ Slapi_DN *sdn;
|
||||
+ char *certify;
|
||||
+ char *force;
|
||||
+ PRBool original_task;
|
||||
+} cleanruv_data;
|
||||
+
|
||||
+typedef struct _cleanruv_purge_data
|
||||
+{
|
||||
+ int cleaned_rid;
|
||||
+ const Slapi_DN *suffix_sdn;
|
||||
+ char *replName;
|
||||
+ char *replGen;
|
||||
+} cleanruv_purge_data;
|
||||
+
|
||||
/* In repl5_replica_config.c */
|
||||
int replica_config_init(void);
|
||||
void replica_config_destroy(void);
|
||||
int get_replica_type(Replica *r);
|
||||
int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid);
|
||||
-void add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing);
|
||||
+void add_cleaned_rid(cleanruv_data *data, char *maxcsn);
|
||||
int is_cleaned_rid(ReplicaId rid);
|
||||
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);
|
||||
@@ -808,29 +833,7 @@ 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);
|
||||
|
||||
-#define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */
|
||||
|
||||
-typedef struct _cleanruv_data
|
||||
-{
|
||||
- Object *repl_obj;
|
||||
- Replica *replica;
|
||||
- ReplicaId rid;
|
||||
- Slapi_Task *task;
|
||||
- struct berval *payload;
|
||||
- CSN *maxcsn;
|
||||
- char *repl_root;
|
||||
- Slapi_DN *sdn;
|
||||
- char *certify;
|
||||
- char *force;
|
||||
-} cleanruv_data;
|
||||
-
|
||||
-typedef struct _cleanruv_purge_data
|
||||
-{
|
||||
- int cleaned_rid;
|
||||
- const Slapi_DN *suffix_sdn;
|
||||
- char *replName;
|
||||
- char *replGen;
|
||||
-} cleanruv_purge_data;
|
||||
|
||||
/* replutil.c */
|
||||
LDAPControl *create_managedsait_control(void);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index 77f4f18e4..e75807a62 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -2120,6 +2120,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
|
||||
char csnstr[CSN_STRSIZE];
|
||||
char *token = NULL;
|
||||
char *forcing;
|
||||
+ PRBool original_task;
|
||||
char *csnpart;
|
||||
char *ridstr;
|
||||
char *iter = NULL;
|
||||
@@ -2151,8 +2152,15 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
|
||||
csn_init_by_string(maxcsn, csnpart);
|
||||
csn_as_string(maxcsn, PR_FALSE, csnstr);
|
||||
forcing = ldap_utf8strtok_r(iter, ":", &iter);
|
||||
+ original_task = PR_TRUE;
|
||||
if (forcing == NULL) {
|
||||
forcing = "no";
|
||||
+ } else if (!strcasecmp(forcing, "yes") || !strcasecmp(forcing, "no")) {
|
||||
+ /* forcing was correctly set, lets try to read the original task flag */
|
||||
+ token = ldap_utf8strtok_r(iter, ":", &iter);
|
||||
+ if (token && !atoi(token)) {
|
||||
+ original_task = PR_FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name, "CleanAllRUV Task - cleanAllRUV task found, "
|
||||
@@ -2190,6 +2198,13 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
|
||||
data->force = slapi_ch_strdup(forcing);
|
||||
data->repl_root = NULL;
|
||||
|
||||
+ /* This is a corner case, a cleanAllRuv task was interrupted by a shutdown or a crash
|
||||
+ * We retrieved from type_replicaCleanRUV if the cleanAllRuv request
|
||||
+ * was received from a direct task ADD or if was received via
|
||||
+ * the cleanAllRuv extop.
|
||||
+ */
|
||||
+ data->original_task = original_task;
|
||||
+
|
||||
thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
|
||||
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
|
||||
@@ -2284,6 +2299,12 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
|
||||
data->sdn = slapi_sdn_dup(r->repl_root);
|
||||
data->certify = slapi_ch_strdup(certify);
|
||||
|
||||
+ /* This is a corner case, a cleanAllRuv task was interrupted by a shutdown or a crash
|
||||
+ * Let's assum this replica was the original receiver of the task.
|
||||
+ * This flag has no impact on Abort cleanAllRuv
|
||||
+ */
|
||||
+ data->original_task = PR_TRUE;
|
||||
+
|
||||
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
|
||||
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 005528a41..95b933bb8 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -1573,6 +1573,11 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
|
||||
data->repl_root = slapi_ch_strdup(basedn);
|
||||
data->force = slapi_ch_strdup(force_cleaning);
|
||||
|
||||
+ /* It is either a consequence of a direct ADD cleanAllRuv task
|
||||
+ * or modify of the replica to add nsds5task: cleanAllRuv
|
||||
+ */
|
||||
+ data->original_task = PR_TRUE;
|
||||
+
|
||||
thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread,
|
||||
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
|
||||
@@ -1702,7 +1707,7 @@ replica_cleanallruv_thread(void *arg)
|
||||
/*
|
||||
* Add the cleanallruv task to the repl config - so we can handle restarts
|
||||
*/
|
||||
- add_cleaned_rid(data->rid, data->replica, csnstr, data->force); /* marks config that we started cleaning a rid */
|
||||
+ add_cleaned_rid(data, csnstr); /* marks config that we started cleaning a rid */
|
||||
cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Cleaning rid (%d)...", data->rid);
|
||||
/*
|
||||
* First, wait for the maxcsn to be covered
|
||||
@@ -1878,7 +1883,13 @@ done:
|
||||
*/
|
||||
delete_cleaned_rid_config(data);
|
||||
check_replicas_are_done_cleaning(data);
|
||||
- remove_keep_alive_entry(data->task, data->rid, data->repl_root);
|
||||
+ if (data->original_task) {
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Original task deletes Keep alive entry (%d).", data->rid);
|
||||
+ remove_keep_alive_entry(data->task, data->rid, data->repl_root);
|
||||
+ } 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);
|
||||
@@ -2029,7 +2040,7 @@ check_replicas_are_done_cleaning(cleanruv_data *data)
|
||||
"Waiting for all the replicas to finish cleaning...");
|
||||
|
||||
csn_as_string(data->maxcsn, PR_FALSE, csnstr);
|
||||
- filter = PR_smprintf("(%s=%d:%s:%s)", type_replicaCleanRUV, (int)data->rid, csnstr, data->force);
|
||||
+ filter = PR_smprintf("(%s=%d:%s:%s:%d)", type_replicaCleanRUV, (int)data->rid, csnstr, data->force, data->original_task ? 1 : 0);
|
||||
while (not_all_cleaned && !is_task_aborted(data->rid) && !slapi_is_shutting_down()) {
|
||||
agmt_obj = agmtlist_get_first_agreement_for_replica(data->replica);
|
||||
if (agmt_obj == NULL) {
|
||||
@@ -2502,7 +2513,7 @@ set_cleaned_rid(ReplicaId rid)
|
||||
* Add the rid and maxcsn to the repl config (so we can resume after a server restart)
|
||||
*/
|
||||
void
|
||||
-add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing)
|
||||
+add_cleaned_rid(cleanruv_data *cleanruv_data, char *maxcsn)
|
||||
{
|
||||
Slapi_PBlock *pb;
|
||||
struct berval *vals[2];
|
||||
@@ -2512,6 +2523,16 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing)
|
||||
char data[CSN_STRSIZE + 10];
|
||||
char *dn;
|
||||
int rc;
|
||||
+ ReplicaId rid;
|
||||
+ Replica *r;
|
||||
+ char *forcing;
|
||||
+
|
||||
+ if (data == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+ rid = cleanruv_data->rid;
|
||||
+ r = cleanruv_data->replica;
|
||||
+ forcing = cleanruv_data->force;
|
||||
|
||||
if (r == NULL || maxcsn == NULL) {
|
||||
return;
|
||||
@@ -2519,7 +2540,7 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing)
|
||||
/*
|
||||
* Write the rid & maxcsn to the config entry
|
||||
*/
|
||||
- val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s", rid, maxcsn, forcing);
|
||||
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s:%d", rid, maxcsn, forcing, cleanruv_data->original_task ? 1 : 0);
|
||||
dn = replica_get_dn(r);
|
||||
pb = slapi_pblock_new();
|
||||
mod.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
|
||||
@@ -2961,6 +2982,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)),
|
||||
data->repl_root = slapi_ch_strdup(base_dn);
|
||||
data->sdn = NULL;
|
||||
data->certify = slapi_ch_strdup(certify_all);
|
||||
+ data->original_task = PR_TRUE;
|
||||
|
||||
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
|
||||
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
||||
index c49c6bd8d..68e2544b4 100644
|
||||
--- a/ldap/servers/plugins/replication/repl_extop.c
|
||||
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
||||
@@ -1412,6 +1412,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
|
||||
data->rid = rid;
|
||||
data->repl_root = slapi_ch_strdup(repl_root);
|
||||
data->certify = slapi_ch_strdup(certify_all);
|
||||
+ data->original_task = PR_FALSE;
|
||||
/*
|
||||
* Set the aborted rid and stop the cleaning
|
||||
*/
|
||||
@@ -1555,6 +1556,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
|
||||
data->payload = slapi_ch_bvdup(extop_payload);
|
||||
data->force = slapi_ch_strdup(force);
|
||||
data->repl_root = slapi_ch_strdup(repl_root);
|
||||
+ data->original_task = PR_FALSE;
|
||||
|
||||
thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
|
||||
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
From cfa194289ee0c9d26d5775f0b67cf9b481bf357f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 12 Jan 2018 10:37:18 -0500
|
||||
Subject: [PATCH] Ticket 49532 - coverity issues - fix compiler warnings &
|
||||
clang issues
|
||||
|
||||
Description: Fixed all the warnings
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49532
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 05907ae05c8a88a64b86747879c002d55d356673)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/idl_set.c | 4 ++--
|
||||
ldap/servers/slapd/control.c | 2 +-
|
||||
src/nunc-stans/ns/ns_thrpool.c | 7 ++++++-
|
||||
3 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
index b68e7ab76..f9a900f1f 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/idl_set.c
|
||||
@@ -270,7 +270,7 @@ idl_set_union(IDListSet *idl_set, backend *be)
|
||||
* Allocate a new set based on the size of our sets.
|
||||
*/
|
||||
IDList *result_list = idl_alloc(idl_set->total_size);
|
||||
- IDList *idl = idl_set->head;
|
||||
+ IDList *idl = NULL;
|
||||
IDList *idl_del = NULL;
|
||||
IDList *prev_idl = NULL;
|
||||
NIDS last_min = 0;
|
||||
@@ -398,7 +398,7 @@ idl_set_intersect(IDListSet *idl_set, backend *be)
|
||||
* we don't care if we have allids here, because we'll ignore it anyway.
|
||||
*/
|
||||
result_list = idl_alloc(idl_set->minimum->b_nids);
|
||||
- IDList *idl = idl_set->head;
|
||||
+ IDList *idl = NULL;
|
||||
|
||||
/* The previous value we inserted. */
|
||||
NIDS last_min = 0;
|
||||
diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c
|
||||
index 91d8abb95..366ec7897 100644
|
||||
--- a/ldap/servers/slapd/control.c
|
||||
+++ b/ldap/servers/slapd/control.c
|
||||
@@ -337,7 +337,7 @@ get_ldapmessage_controls_ext(
|
||||
slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &ctrl_not_found);
|
||||
slapi_pblock_set(pb, SLAPI_PWPOLICY, &ctrl_not_found);
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "get_ldapmessage_controls_ext", "Warning: conn=%" PRIu64 " op=%d contains an empty list of controls\n",
|
||||
- pb_conn->c_connid, pb_op->o_opid);
|
||||
+ pb_conn ? pb_conn->c_connid : -1, pb_op ? pb_op->o_opid : -1);
|
||||
} else {
|
||||
/* len, ber_len_t is uint, not int, cannot be != -1, may be better to remove this check. */
|
||||
if ((tag != LBER_END_OF_SEQORSET) && (len != -1)) {
|
||||
diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c
|
||||
index 1d8bb03f1..d95b0c38b 100644
|
||||
--- a/src/nunc-stans/ns/ns_thrpool.c
|
||||
+++ b/src/nunc-stans/ns/ns_thrpool.c
|
||||
@@ -1587,7 +1587,12 @@ ns_thrpool_shutdown(struct ns_thrpool_t *tp)
|
||||
*/
|
||||
for (size_t i = 0; i < tp->thread_count; i++) {
|
||||
ns_result_t result = ns_add_shutdown_job(tp);
|
||||
- PR_ASSERT(result == NS_SUCCESS);
|
||||
+ if (result != NS_SUCCESS) {
|
||||
+#ifdef DEBUG
|
||||
+ ns_log(LOG_DEBUG, "ns_thrpool_shutdown - Failed to add shutdown job: error (%d)\n", result);
|
||||
+#endif
|
||||
+ PR_ASSERT(0);
|
||||
+ }
|
||||
}
|
||||
/* Make sure all threads are woken up to their shutdown jobs. */
|
||||
pthread_mutex_lock(&(tp->work_q_lock));
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
From 60198729ba59f673aae2ae1db1d9668b674ad429 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 5 Jan 2018 15:31:44 +0100
|
||||
Subject: [PATCH] Ticket 49523 - memberof: schema violation error message is
|
||||
confusing as memberof will likely repair target entry
|
||||
|
||||
Bug Description:
|
||||
When memberof is enabled it adds 'memberof' attribute to members entries.
|
||||
If a member entry has not the appropriate objectclass to support 'memberof' attribute an ERR is logged.
|
||||
|
||||
ERR - oc_check_allowed_sv - Entry "cn=user_1,ou=People,dc=example,dc=com" -- attribute "memberOf" not allowed
|
||||
|
||||
This is confusing because memberof will catch this violation and may try to repair it.
|
||||
So although this message is alarming, the target entry may finally have the 'memberof' attribute.
|
||||
|
||||
This is especially confusing since https://pagure.io/389-ds-base/issue/48985 where the repair operation
|
||||
is done by default (if schema is violated)
|
||||
|
||||
We can not (and should not) eliminate the schema violation message.
|
||||
But memberof should log a additional warning (beside the schema violation msg) stating it repaired the violation.
|
||||
|
||||
Fix Description:
|
||||
|
||||
Add a warning message upon repair operation
|
||||
ERR - oc_check_allowed_sv - Entry "<entry_dn>" -- attribute "memberOf" not allowed
|
||||
WARN - memberof-plugin - Entry <entry_dn> - schema violation caught - repair operation succeeded
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49523
|
||||
|
||||
Reviewed by: Mark Reynolds
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49523_test.py | 154 ++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/memberof/memberof.c | 8 +-
|
||||
2 files changed, 161 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49523_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49523_test.py b/dirsrvtests/tests/tickets/ticket49523_test.py
|
||||
new file mode 100644
|
||||
index 000000000..c3296ef07
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49523_test.py
|
||||
@@ -0,0 +1,154 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import ldap
|
||||
+import time
|
||||
+import re
|
||||
+from lib389.plugins import MemberOfPlugin
|
||||
+from lib389._constants import *
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+from lib389 import Entry
|
||||
+
|
||||
+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__)
|
||||
+
|
||||
+
|
||||
+USER_CN='user_'
|
||||
+GROUP_CN='group_'
|
||||
+def _user_get_dn(no):
|
||||
+ cn = '%s%d' % (USER_CN, no)
|
||||
+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
|
||||
+ return (cn, dn)
|
||||
+
|
||||
+def add_user(server, no, desc='dummy', sleep=True):
|
||||
+ (cn, dn) = _user_get_dn(no)
|
||||
+ log.fatal('Adding user (%s): ' % dn)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'person'],
|
||||
+ 'cn': [cn],
|
||||
+ 'description': [desc],
|
||||
+ 'sn': [cn],
|
||||
+ 'description': ['add on that host']})))
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def add_group(server, nr, sleep=True):
|
||||
+ cn = '%s%d' % (GROUP_CN, nr)
|
||||
+ dn = 'cn=%s,ou=groups,%s' % (cn, SUFFIX)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'],
|
||||
+ 'description': 'group %d' % nr})))
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def update_member(server, member_dn, group_dn, op, sleep=True):
|
||||
+ mod = [(op, 'member', member_dn)]
|
||||
+ server.modify_s(group_dn, mod)
|
||||
+ if sleep:
|
||||
+ time.sleep(2)
|
||||
+
|
||||
+def _find_memberof(server, member_dn, group_dn, find_result=True):
|
||||
+ ent = server.getEntry(member_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof'])
|
||||
+ found = False
|
||||
+ if ent.hasAttr('memberof'):
|
||||
+
|
||||
+ for val in ent.getValues('memberof'):
|
||||
+ server.log.info("!!!!!!! %s: memberof->%s" % (member_dn, val))
|
||||
+ server.log.info("!!!!!!! %s" % (val))
|
||||
+ server.log.info("!!!!!!! %s" % (group_dn))
|
||||
+ if val.lower() == group_dn.lower():
|
||||
+ found = True
|
||||
+ break
|
||||
+
|
||||
+ if find_result:
|
||||
+ assert (found)
|
||||
+ else:
|
||||
+ assert (not found)
|
||||
+
|
||||
+def pattern_accesslog(server, log_pattern):
|
||||
+ file_obj = open(server.accesslog, "r")
|
||||
+
|
||||
+ found = False
|
||||
+ # Use a while true iteration because 'for line in file: hit a
|
||||
+ while True:
|
||||
+ line = file_obj.readline()
|
||||
+ found = log_pattern.search(line)
|
||||
+ if ((line == '') or (found)):
|
||||
+ break
|
||||
+
|
||||
+ return found
|
||||
+
|
||||
+def pattern_errorlog(server, log_pattern):
|
||||
+ file_obj = open(server.errlog, "r")
|
||||
+
|
||||
+ found = None
|
||||
+ # Use a while true iteration because 'for line in file: hit a
|
||||
+ while True:
|
||||
+ line = file_obj.readline()
|
||||
+ found = log_pattern.search(line)
|
||||
+ server.log.fatal("%s --> %s" % (line, found))
|
||||
+ if ((line == '') or (found)):
|
||||
+ break
|
||||
+
|
||||
+ return found
|
||||
+
|
||||
+def test_ticket49523(topo):
|
||||
+ """Specify a test case purpose or name here
|
||||
+
|
||||
+ :id: e2af0aaa-447e-4e85-a5ce-57ae66260d0b
|
||||
+ :setup: Fill in set up configuration here
|
||||
+ :steps:
|
||||
+ 1. Fill in test case steps here
|
||||
+ 2. And indent them like this (RST format requirement)
|
||||
+ :expectedresults:
|
||||
+ 1. Fill in the result that is expected
|
||||
+ 2. For each test step
|
||||
+ """
|
||||
+
|
||||
+ # If you need any test suite initialization,
|
||||
+ # please, write additional fixture for that (including finalizer).
|
||||
+ # Topology for suites are predefined in lib389/topologies.py.
|
||||
+
|
||||
+ # If you need host, port or any other data about instance,
|
||||
+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
|
||||
+ inst = topo.standalone
|
||||
+ memberof = MemberOfPlugin(inst)
|
||||
+ memberof.enable()
|
||||
+ memberof.set_autoaddoc('nsMemberOf')
|
||||
+ inst.restart()
|
||||
+
|
||||
+ # Step 2
|
||||
+ for i in range(10):
|
||||
+ add_user(inst, i, desc='add user')
|
||||
+
|
||||
+ add_group(inst, 1)
|
||||
+
|
||||
+ group_parent_dn = 'ou=groups,%s' % (SUFFIX)
|
||||
+ group_rdn = 'cn=%s%d' % (GROUP_CN, 1)
|
||||
+ group_dn = '%s,%s' % (group_rdn, group_parent_dn)
|
||||
+ (member_cn, member_dn) = _user_get_dn(1)
|
||||
+ update_member(inst, member_dn, group_dn, ldap.MOD_ADD, sleep=False)
|
||||
+
|
||||
+ _find_memberof(inst, member_dn, group_dn, find_result=True)
|
||||
+
|
||||
+ pattern = ".*oc_check_allowed_sv - Entry.*cn=%s.* -- attribute.*not allowed.*" % member_cn
|
||||
+ log.fatal("pattern = %s" % pattern)
|
||||
+ regex = re.compile(pattern)
|
||||
+ assert pattern_errorlog(inst, regex)
|
||||
+
|
||||
+ regex = re.compile(".*schema violation caught - repair operation.*")
|
||||
+ assert pattern_errorlog(inst, regex)
|
||||
+
|
||||
+ if DEBUGGING:
|
||||
+ # Add debugging steps(if any)...
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index 44b52edbb..fcfa7817d 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -3236,8 +3236,14 @@ memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
- if (memberof_add_objectclass(add_oc, dn)) {
|
||||
+ rc = memberof_add_objectclass(add_oc, dn);
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, MEMBEROF_PLUGIN_SUBSYSTEM,
|
||||
+ "Entry %s - schema violation caught - repair operation %s\n",
|
||||
+ dn ? dn : "unknown",
|
||||
+ rc ? "failed" : "succeeded");
|
||||
+ if (rc) {
|
||||
/* Failed to add objectclass */
|
||||
+ rc = LDAP_OBJECT_CLASS_VIOLATION;
|
||||
break;
|
||||
}
|
||||
added_oc = 1;
|
||||
--
|
||||
2.13.6
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,288 +0,0 @@
|
|||
From 86efa0314c59550f0660c8d143a52a57b1dffb96 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 18 Jan 2018 09:56:17 -0500
|
||||
Subject: [PATCH] Ticket 49370 - Add all the password policy defaults to a new
|
||||
local policy
|
||||
|
||||
Bug Description: When processing a local password policy we were not pulling
|
||||
in the defaults for the "on/off" settings. This patch
|
||||
addresses that.
|
||||
|
||||
Fix Description: Create common default init functions for all password policies
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49370
|
||||
|
||||
Reviewed by: tbordaz, wibrown, and spichugi (Thanks!!!)
|
||||
|
||||
(cherry picked from commit c8b388bf9f5269e1e1dc8c7c70ec8e58e825204a)
|
||||
---
|
||||
.../tests/suites/password/regression_test.py | 58 +++++++++++++--
|
||||
ldap/servers/slapd/libglobs.c | 84 ++++++++++++++--------
|
||||
ldap/servers/slapd/pw.c | 29 ++------
|
||||
ldap/servers/slapd/slap.h | 2 +
|
||||
4 files changed, 113 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/password/regression_test.py b/dirsrvtests/tests/suites/password/regression_test.py
|
||||
index f6ee16773..800294057 100644
|
||||
--- a/dirsrvtests/tests/suites/password/regression_test.py
|
||||
+++ b/dirsrvtests/tests/suites/password/regression_test.py
|
||||
@@ -6,9 +6,10 @@
|
||||
# --- END COPYRIGHT BLOCK ---
|
||||
#
|
||||
import pytest
|
||||
-from lib389._constants import SUFFIX, PASSWORD
|
||||
+import time
|
||||
+from lib389._constants import SUFFIX, PASSWORD, DN_DM
|
||||
from lib389.idm.user import UserAccounts
|
||||
-from lib389.utils import ldap, os, logging
|
||||
+from lib389.utils import ldap, os, logging, ensure_bytes
|
||||
from lib389.topologies import topology_st as topo
|
||||
|
||||
DEBUGGING = os.getenv("DEBUGGING", default=False)
|
||||
@@ -20,6 +21,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
user_data = {'cn': 'CNpwtest1', 'sn': 'SNpwtest1', 'uid': 'UIDpwtest1', 'mail': 'MAILpwtest1@redhat.com',
|
||||
'givenname': 'GNpwtest1'}
|
||||
+
|
||||
TEST_PASSWORDS = list(user_data.values())
|
||||
# Add substring/token values of "CNpwtest1"
|
||||
TEST_PASSWORDS += ['CNpwtest1ZZZZ', 'ZZZZZCNpwtest1',
|
||||
@@ -37,13 +39,20 @@ def passw_policy(topo, request):
|
||||
"""Configure password policy with PasswordCheckSyntax attribute set to on"""
|
||||
|
||||
log.info('Configure Pwpolicy with PasswordCheckSyntax and nsslapd-pwpolicy-local set to on')
|
||||
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
||||
topo.standalone.config.set('PasswordExp', 'on')
|
||||
topo.standalone.config.set('PasswordCheckSyntax', 'off')
|
||||
topo.standalone.config.set('nsslapd-pwpolicy-local', 'on')
|
||||
|
||||
subtree = 'ou=people,{}'.format(SUFFIX)
|
||||
log.info('Configure subtree password policy for {}'.format(subtree))
|
||||
- topo.standalone.subtreePwdPolicy(subtree, {'passwordchange': 'on', 'passwordCheckSyntax': 'on'})
|
||||
+ topo.standalone.subtreePwdPolicy(subtree, {'passwordchange': ensure_bytes('on'),
|
||||
+ 'passwordCheckSyntax': ensure_bytes('on'),
|
||||
+ 'passwordLockout': ensure_bytes('on'),
|
||||
+ 'passwordResetFailureCount': ensure_bytes('3'),
|
||||
+ 'passwordLockoutDuration': ensure_bytes('3'),
|
||||
+ 'passwordMaxFailure': ensure_bytes('2')})
|
||||
+ time.sleep(1)
|
||||
|
||||
def fin():
|
||||
log.info('Reset pwpolicy configuration settings')
|
||||
@@ -76,6 +85,47 @@ def test_user(topo, request):
|
||||
return tuser
|
||||
|
||||
|
||||
+def test_pwp_local_unlock(topo, passw_policy, test_user):
|
||||
+ """Test subtree policies use the same global default for passwordUnlock
|
||||
+
|
||||
+ :id: 741a8417-5f65-4012-b9ed-87987ce3ca1b
|
||||
+ :setup: Standalone instance
|
||||
+ :steps:
|
||||
+ 1. Test user can bind
|
||||
+ 2. Bind with bad passwords to lockout account, and verify account is locked
|
||||
+ 3. Wait for lockout interval, and bind with valid password
|
||||
+ :expectedresults:
|
||||
+ 1. Bind successful
|
||||
+ 2. Entry is locked
|
||||
+ 3. Entry can bind with correct password
|
||||
+ """
|
||||
+
|
||||
+ log.info("Verify user can bind...")
|
||||
+ test_user.bind(PASSWORD)
|
||||
+
|
||||
+ log.info('Test passwordUnlock default - user should be able to reset password after lockout')
|
||||
+ for i in range(0,2):
|
||||
+ try:
|
||||
+ test_user.bind("bad-password")
|
||||
+ except ldap.INVALID_CREDENTIALS:
|
||||
+ # expected
|
||||
+ pass
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal("Got unexpected failure: " + atr(e))
|
||||
+ raise e
|
||||
+
|
||||
+
|
||||
+ log.info('Verify account is locked')
|
||||
+ with pytest.raises(ldap.CONSTRAINT_VIOLATION):
|
||||
+ test_user.bind(PASSWORD)
|
||||
+
|
||||
+ log.info('Wait for lockout duration...')
|
||||
+ time.sleep(4)
|
||||
+
|
||||
+ log.info('Check if user can now bind with correct password')
|
||||
+ test_user.bind(PASSWORD)
|
||||
+
|
||||
+
|
||||
@pytest.mark.bz1465600
|
||||
@pytest.mark.parametrize("user_pasw", TEST_PASSWORDS)
|
||||
def test_trivial_passw_check(topo, passw_policy, test_user, user_pasw):
|
||||
@@ -143,4 +193,4 @@ if __name__ == '__main__':
|
||||
# Run isolated
|
||||
# -s for DEBUG mode
|
||||
CURRENT_FILE = os.path.realpath(__file__)
|
||||
- pytest.main("-s {}".format(CURRENT_FILE))
|
||||
+ pytest.main(["-s", CURRENT_FILE])
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index 1ba30002f..c1a765aca 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -1401,6 +1401,56 @@ getFrontendConfig(void)
|
||||
*/
|
||||
|
||||
void
|
||||
+pwpolicy_init_defaults (passwdPolicy *pw_policy)
|
||||
+{
|
||||
+ pw_policy->pw_change = LDAP_ON;
|
||||
+ pw_policy->pw_must_change = LDAP_OFF;
|
||||
+ pw_policy->pw_syntax = LDAP_OFF;
|
||||
+ pw_policy->pw_exp = LDAP_OFF;
|
||||
+ pw_policy->pw_send_expiring = LDAP_OFF;
|
||||
+ pw_policy->pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH;
|
||||
+ pw_policy->pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS;
|
||||
+ pw_policy->pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS;
|
||||
+ pw_policy->pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS;
|
||||
+ pw_policy->pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS;
|
||||
+ pw_policy->pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS;
|
||||
+ pw_policy->pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT;
|
||||
+ pw_policy->pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS;
|
||||
+ pw_policy->pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES;
|
||||
+ pw_policy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
+ pw_policy->pw_maxage = SLAPD_DEFAULT_PW_MAXAGE;
|
||||
+ pw_policy->pw_minage = SLAPD_DEFAULT_PW_MINAGE;
|
||||
+ pw_policy->pw_warning = SLAPD_DEFAULT_PW_WARNING;
|
||||
+ pw_policy->pw_history = LDAP_OFF;
|
||||
+ pw_policy->pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY;
|
||||
+ pw_policy->pw_lockout = LDAP_OFF;
|
||||
+ pw_policy->pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE;
|
||||
+ pw_policy->pw_unlock = LDAP_ON;
|
||||
+ pw_policy->pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION;
|
||||
+ pw_policy->pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT;
|
||||
+ pw_policy->pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT;
|
||||
+ pw_policy->pw_admin = NULL;
|
||||
+ pw_policy->pw_admin_user = NULL;
|
||||
+ pw_policy->pw_is_legacy = LDAP_ON;
|
||||
+ pw_policy->pw_track_update_time = LDAP_OFF;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+pwpolicy_fe_init_onoff(passwdPolicy *pw_policy)
|
||||
+{
|
||||
+ init_pw_change = pw_policy->pw_change;
|
||||
+ init_pw_must_change = pw_policy->pw_must_change;
|
||||
+ init_pw_syntax = pw_policy->pw_syntax;
|
||||
+ init_pw_exp = pw_policy->pw_exp;
|
||||
+ init_pw_send_expiring = pw_policy->pw_send_expiring;
|
||||
+ init_pw_history = pw_policy->pw_history;
|
||||
+ init_pw_lockout = pw_policy->pw_lockout;
|
||||
+ init_pw_unlock = pw_policy->pw_unlock;
|
||||
+ init_pw_is_legacy = pw_policy->pw_is_legacy;
|
||||
+ init_pw_track_update_time = pw_policy->pw_track_update_time;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
FrontendConfig_init(void)
|
||||
{
|
||||
slapdFrontendConfig_t *cfg = getFrontendConfig();
|
||||
@@ -1511,41 +1561,13 @@ FrontendConfig_init(void)
|
||||
* let clients abide by the LDAP standards and send us a SASL/EXTERNAL bind
|
||||
* if that's what they want to do */
|
||||
init_force_sasl_external = cfg->force_sasl_external = LDAP_OFF;
|
||||
-
|
||||
init_readonly = cfg->readonly = LDAP_OFF;
|
||||
+
|
||||
+ pwpolicy_init_defaults(&cfg->pw_policy);
|
||||
+ pwpolicy_fe_init_onoff(&cfg->pw_policy);
|
||||
init_pwpolicy_local = cfg->pwpolicy_local = LDAP_OFF;
|
||||
init_pwpolicy_inherit_global = cfg->pwpolicy_inherit_global = LDAP_OFF;
|
||||
- init_pw_change = cfg->pw_policy.pw_change = LDAP_ON;
|
||||
- init_pw_must_change = cfg->pw_policy.pw_must_change = LDAP_OFF;
|
||||
init_allow_hashed_pw = cfg->allow_hashed_pw = LDAP_OFF;
|
||||
- init_pw_syntax = cfg->pw_policy.pw_syntax = LDAP_OFF;
|
||||
- init_pw_exp = cfg->pw_policy.pw_exp = LDAP_OFF;
|
||||
- init_pw_send_expiring = cfg->pw_policy.pw_send_expiring = LDAP_OFF;
|
||||
- cfg->pw_policy.pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH;
|
||||
- cfg->pw_policy.pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS;
|
||||
- cfg->pw_policy.pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS;
|
||||
- cfg->pw_policy.pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS;
|
||||
- cfg->pw_policy.pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS;
|
||||
- cfg->pw_policy.pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS;
|
||||
- cfg->pw_policy.pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT;
|
||||
- cfg->pw_policy.pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS;
|
||||
- cfg->pw_policy.pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES;
|
||||
- cfg->pw_policy.pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
- cfg->pw_policy.pw_maxage = SLAPD_DEFAULT_PW_MAXAGE;
|
||||
- cfg->pw_policy.pw_minage = SLAPD_DEFAULT_PW_MINAGE;
|
||||
- cfg->pw_policy.pw_warning = SLAPD_DEFAULT_PW_WARNING;
|
||||
- init_pw_history = cfg->pw_policy.pw_history = LDAP_OFF;
|
||||
- cfg->pw_policy.pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY;
|
||||
- init_pw_lockout = cfg->pw_policy.pw_lockout = LDAP_OFF;
|
||||
- cfg->pw_policy.pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE;
|
||||
- init_pw_unlock = cfg->pw_policy.pw_unlock = LDAP_ON;
|
||||
- cfg->pw_policy.pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION;
|
||||
- cfg->pw_policy.pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT;
|
||||
- cfg->pw_policy.pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT;
|
||||
- cfg->pw_policy.pw_admin = NULL;
|
||||
- cfg->pw_policy.pw_admin_user = NULL;
|
||||
- init_pw_is_legacy = cfg->pw_policy.pw_is_legacy = LDAP_ON;
|
||||
- init_pw_track_update_time = cfg->pw_policy.pw_track_update_time = LDAP_OFF;
|
||||
init_pw_is_global_policy = cfg->pw_is_global_policy = LDAP_OFF;
|
||||
|
||||
init_accesslog_logging_enabled = cfg->accesslog_logging_enabled = LDAP_ON;
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index 53464c64a..3a545e12e 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -1730,32 +1730,11 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
goto done;
|
||||
}
|
||||
|
||||
- /* Set the default values */
|
||||
- pwdpolicy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
- pwdpolicy->pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH;
|
||||
- pwdpolicy->pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS;
|
||||
- pwdpolicy->pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS;
|
||||
- pwdpolicy->pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS;
|
||||
- pwdpolicy->pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS;
|
||||
- pwdpolicy->pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS;
|
||||
- pwdpolicy->pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT;
|
||||
- pwdpolicy->pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS;
|
||||
- pwdpolicy->pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES;
|
||||
- pwdpolicy->pw_maxage = SLAPD_DEFAULT_PW_MAXAGE;
|
||||
- pwdpolicy->pw_minage = SLAPD_DEFAULT_PW_MINAGE;
|
||||
- pwdpolicy->pw_warning = SLAPD_DEFAULT_PW_WARNING;
|
||||
- pwdpolicy->pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY;
|
||||
- pwdpolicy->pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE;
|
||||
- pwdpolicy->pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION;
|
||||
- pwdpolicy->pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT;
|
||||
- pwdpolicy->pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT;
|
||||
-
|
||||
- /* set the default passwordLegacyPolicy setting */
|
||||
- pwdpolicy->pw_is_legacy = 1;
|
||||
-
|
||||
- /* set passwordTrackUpdateTime */
|
||||
- pwdpolicy->pw_track_update_time = slapdFrontendConfig->pw_policy.pw_track_update_time;
|
||||
+ /* Set the default values (from libglobs.c) */
|
||||
+ pwpolicy_init_defaults(pwdpolicy);
|
||||
+ pwdpolicy->pw_storagescheme = slapdFrontendConfig->pw_storagescheme;
|
||||
|
||||
+ /* Set the defined values now */
|
||||
for (slapi_entry_first_attr(pw_entry, &attr); attr;
|
||||
slapi_entry_next_attr(pw_entry, attr, &attr)) {
|
||||
slapi_attr_get_type(attr, &attr_name);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 08754d8fb..f6fc374a4 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1773,6 +1773,8 @@ typedef struct passwordpolicyarray
|
||||
Slapi_DN **pw_admin_user;
|
||||
} passwdPolicy;
|
||||
|
||||
+void pwpolicy_init_defaults (passwdPolicy *pw_policy);
|
||||
+
|
||||
Slapi_PBlock *slapi_pblock_clone(Slapi_PBlock *pb); /* deprecated */
|
||||
|
||||
passwdPolicy *slapi_pblock_get_pwdpolicy(Slapi_PBlock *pb);
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From 38ca528af83f1874a79ad6744215bd4af1404414 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 18 Jan 2018 13:17:08 -0500
|
||||
Subject: [PATCH] Ticket 49541 - repl config should not allow rid 65535 for
|
||||
masters
|
||||
|
||||
Description: Reject adding a replica config entry with a rid of 65535 or higher,
|
||||
and prevent setting master's rid to 65535 or higher.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49541
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
|
||||
(cherry picked from commit ebb00a4180693225cf3c2f4aced54dc33141fa77)
|
||||
---
|
||||
dirsrvtests/tests/suites/replication/replica_config_test.py | 9 +++++----
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 2 +-
|
||||
2 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py
|
||||
index 50ea2ece9..143a12479 100644
|
||||
--- a/dirsrvtests/tests/suites/replication/replica_config_test.py
|
||||
+++ b/dirsrvtests/tests/suites/replication/replica_config_test.py
|
||||
@@ -24,7 +24,7 @@ replica_dict = {'objectclass': 'top nsDS5Replica'.split(),
|
||||
'nsDS5ReplicaRoot': 'dc=example,dc=com',
|
||||
'nsDS5ReplicaType': '3',
|
||||
'nsDS5Flags': '1',
|
||||
- 'nsDS5ReplicaId': '65535',
|
||||
+ 'nsDS5ReplicaId': '65534',
|
||||
'nsds5ReplicaPurgeDelay': '604800',
|
||||
'nsDS5ReplicaBindDN': 'cn=u',
|
||||
'cn': 'replica'}
|
||||
@@ -42,7 +42,7 @@ agmt_dict = {'objectClass': 'top nsDS5ReplicationAgreement'.split(),
|
||||
|
||||
repl_add_attrs = [('nsDS5ReplicaType', '-1', '4', overflow, notnum, '1'),
|
||||
('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
|
||||
- ('nsDS5ReplicaId', '0', '65536', overflow, notnum, '1'),
|
||||
+ ('nsDS5ReplicaId', '0', '65535', overflow, notnum, '1'),
|
||||
('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'),
|
||||
('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'),
|
||||
('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'),
|
||||
@@ -60,7 +60,8 @@ repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
|
||||
('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'),
|
||||
('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')]
|
||||
|
||||
-agmt_attrs = [('nsds5ReplicaPort', '0', '65536', overflow, notnum, '389'),
|
||||
+agmt_attrs = [
|
||||
+ ('nsds5ReplicaPort', '0', '65535', overflow, notnum, '389'),
|
||||
('nsds5ReplicaTimeout', '-1', too_big, overflow, notnum, '6'),
|
||||
('nsds5ReplicaBusyWaitTime', '-1', too_big, overflow, notnum, '6'),
|
||||
('nsds5ReplicaSessionPauseTime', '-1', too_big, overflow, notnum, '6'),
|
||||
@@ -393,5 +394,5 @@ if __name__ == '__main__':
|
||||
# Run isolated
|
||||
# -s for DEBUG mode
|
||||
CURRENT_FILE = os.path.realpath(__file__)
|
||||
- pytest.main("-s %s" % CURRENT_FILE)
|
||||
+ pytest.main(["-s", CURRENT_FILE])
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index e75807a62..bdb8a5167 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -1988,7 +1988,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
|
||||
r->repl_type == REPLICA_TYPE_PRIMARY) {
|
||||
if ((val = slapi_entry_attr_get_charptr(e, attr_replicaId))) {
|
||||
int64_t rid;
|
||||
- if (repl_config_valid_num(attr_replicaId, val, 1, 65535, &rc, errormsg, &rid) != 0) {
|
||||
+ if (repl_config_valid_num(attr_replicaId, val, 1, 65534, &rc, errormsg, &rid) != 0) {
|
||||
slapi_ch_free_string(&val);
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
From cb008bcace2510f157ccec2df4e5ff254513b7c4 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 10:24:41 +0100
|
||||
Subject: [PATCH] CVE 2017-15134 - crash in slapi_filter_sprintf
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
|
||||
index a72de9b07..ddb2cc899 100644
|
||||
--- a/ldap/servers/slapd/util.c
|
||||
+++ b/ldap/servers/slapd/util.c
|
||||
@@ -238,9 +238,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ])
|
||||
struct filter_ctx
|
||||
{
|
||||
char *buf;
|
||||
- char attr[ATTRSIZE];
|
||||
+ char *attr;
|
||||
int attr_position;
|
||||
int attr_found;
|
||||
+ size_t attr_size;
|
||||
int buf_size;
|
||||
int buf_len;
|
||||
int next_arg_needs_esc_norm;
|
||||
@@ -279,7 +280,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
* Start collecting the attribute name so we can use the correct
|
||||
* syntax normalization func.
|
||||
*/
|
||||
- if (ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)) {
|
||||
+ if (ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) {
|
||||
if (ctx->attr[0] == '\0') {
|
||||
if (strstr(val, "=")) {
|
||||
/* we have an attr we need to record */
|
||||
@@ -293,6 +294,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
* attr with val. The next pass should be '=', otherwise we will
|
||||
* reset it.
|
||||
*/
|
||||
+ if (slen > ctx->attr_size) {
|
||||
+ if (ctx->attr_size == ATTRSIZE) {
|
||||
+ ctx->attr = slapi_ch_calloc(sizeof(char), slen+1);
|
||||
+ } else {
|
||||
+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1));
|
||||
+ }
|
||||
+ ctx->attr_size = slen+1;
|
||||
+ }
|
||||
memcpy(ctx->attr, val, slen);
|
||||
ctx->attr_position = slen;
|
||||
}
|
||||
@@ -302,9 +311,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
} else {
|
||||
if (special_attr_char(val[0])) {
|
||||
/* this is not an attribute, we should not be collecting this, reset everything */
|
||||
- memset(ctx->attr, '\0', ATTRSIZE);
|
||||
+ memset(ctx->attr, '\0', ctx->attr_size);
|
||||
ctx->attr_position = 0;
|
||||
} else {
|
||||
+ /* we can be adding char by char and overrun allocated size */
|
||||
+ if (ctx->attr_position >= ctx->attr_size) {
|
||||
+ if (ctx->attr_size == ATTRSIZE) {
|
||||
+ char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE);
|
||||
+ memcpy(ctxattr, ctx->attr, ctx->attr_size);
|
||||
+ ctx->attr = ctxattr;
|
||||
+ } else {
|
||||
+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE));
|
||||
+ }
|
||||
+ ctx->attr_size = ctx->attr_size + ATTRSIZE;
|
||||
+ }
|
||||
memcpy(ctx->attr + ctx->attr_position, val, 1);
|
||||
ctx->attr_position++;
|
||||
}
|
||||
@@ -377,7 +397,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
ctx->next_arg_needs_esc_norm = 0;
|
||||
ctx->attr_found = 0;
|
||||
ctx->attr_position = 0;
|
||||
- memset(ctx->attr, '\0', ATTRSIZE);
|
||||
+ memset(ctx->attr, '\0', ctx->attr_size);
|
||||
slapi_ch_free_string(&buf);
|
||||
|
||||
return filter_len;
|
||||
@@ -416,12 +436,14 @@ slapi_filter_sprintf(const char *fmt, ...)
|
||||
{
|
||||
struct filter_ctx ctx = {0};
|
||||
va_list args;
|
||||
+ char attr_static[ATTRSIZE] = {0};
|
||||
char *buf;
|
||||
int rc;
|
||||
|
||||
buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1);
|
||||
ctx.buf = buf;
|
||||
- memset(ctx.attr, '\0', ATTRSIZE);
|
||||
+ ctx.attr = attr_static;
|
||||
+ ctx.attr_size = ATTRSIZE;
|
||||
ctx.attr_position = 0;
|
||||
ctx.attr_found = 0;
|
||||
ctx.buf_len = FILTER_BUF;
|
||||
@@ -438,6 +460,10 @@ slapi_filter_sprintf(const char *fmt, ...)
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
+ if (ctx.attr_size > ATTRSIZE) {
|
||||
+ slapi_ch_free_string(&ctx.attr);
|
||||
+ }
|
||||
+
|
||||
return ctx.buf;
|
||||
}
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 3c605035eff49e603c8e4a4c0886499913924529 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 24 Jan 2018 14:24:08 -0500
|
||||
Subject: [PATCH] Ticket 49534 - Fix coverity regression
|
||||
|
||||
Description: In automembers plugin a free was in the wrong spot
|
||||
which later led to a double free for the "rule".
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49534
|
||||
|
||||
Reviewed by: mreynolds (one line commit rule)
|
||||
|
||||
(cherry picked from commit b3768e602fdfc2ea1fc645b17ad61c8592ab87fa)
|
||||
---
|
||||
ldap/servers/plugins/automember/automember.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
|
||||
index cbd25915a..c91aa4e8e 100644
|
||||
--- a/ldap/servers/plugins/automember/automember.c
|
||||
+++ b/ldap/servers/plugins/automember/automember.c
|
||||
@@ -1117,11 +1117,11 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e)
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ automember_free_regex_rule(rule);
|
||||
} else {
|
||||
/* Add to head of list */
|
||||
PR_INSERT_LINK(&(rule->list), (PRCList *)config->exclusive_rules);
|
||||
}
|
||||
- automember_free_regex_rule(rule);
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_ERR, AUTOMEMBER_PLUGIN_SUBSYSTEM,
|
||||
"automember_parse_regex_entry - Skipping invalid exclusive "
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From d39be97021f273548957a9f26ca35d5faab20318 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 29 Jan 2018 21:13:16 -0500
|
||||
Subject: [PATCH] Ticket 49541 - Replica ID config validation fix
|
||||
|
||||
Description: Is is possible to set the replica ID to 65535 with a modify
|
||||
operation, which is reserved for hubs/consumers.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49541
|
||||
|
||||
Reviewed by: mreynolds (one line commit rule)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica_config.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index bda333362..ea430d9a4 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -421,7 +421,7 @@ replica_config_modify(Slapi_PBlock *pb,
|
||||
}
|
||||
} else if (strcasecmp(config_attr, attr_replicaId) == 0) {
|
||||
int64_t rid = 0;
|
||||
- if (repl_config_valid_num(config_attr, config_attr_value, 1, 65535, returncode, errortext, &rid) == 0) {
|
||||
+ if (repl_config_valid_num(config_attr, config_attr_value, 1, 65534, returncode, errortext, &rid) == 0) {
|
||||
slapi_ch_free_string(&new_repl_id);
|
||||
new_repl_id = slapi_ch_strdup(config_attr_value);
|
||||
} else {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
From 3bdd7b5cccd2993c5ae5b9d893be15c71373aaf8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 29 Jan 2018 11:53:33 -0500
|
||||
Subject: [PATCH] Ticket 49370 - Crash when using a global and local pw
|
||||
policies
|
||||
|
||||
Description: This a regression from the previous patch. We were
|
||||
accidently using a reference to the global pw policy
|
||||
password storage scheme, which was getting freed after
|
||||
pblock was done from an operation. The next operation
|
||||
then used(and double freed) this memory on the next
|
||||
operation.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49370
|
||||
|
||||
Reviewed by: tbordaz (Thanks!)
|
||||
|
||||
(cherry picked from commit d86e0f9634e694feb378ee335d29b2e89fd27e2c)
|
||||
---
|
||||
ldap/servers/slapd/pw.c | 32 +++++++++++++++++---------------
|
||||
1 file changed, 17 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index 3a545e12e..451be364d 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -209,7 +209,7 @@ pw_name2scheme(char *name)
|
||||
struct pw_scheme *pwsp;
|
||||
struct slapdplugin *p;
|
||||
|
||||
- if ((p = plugin_get_pwd_storage_scheme(name, strlen(name), PLUGIN_LIST_PWD_STORAGE_SCHEME)) != NULL) {
|
||||
+ if (name != NULL && (p = plugin_get_pwd_storage_scheme(name, strlen(name), PLUGIN_LIST_PWD_STORAGE_SCHEME)) != NULL) {
|
||||
pwsp = (struct pw_scheme *)slapi_ch_malloc(sizeof(struct pw_scheme));
|
||||
if (pwsp != NULL) {
|
||||
typedef int (*CMPFP)(char *, char *);
|
||||
@@ -1612,18 +1612,18 @@ pw_get_admin_users(passwdPolicy *pwp)
|
||||
passwdPolicy *
|
||||
new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
{
|
||||
+ slapdFrontendConfig_t *slapdFrontendConfig = NULL;
|
||||
Slapi_ValueSet *values = NULL;
|
||||
+ Slapi_Value **sval = NULL;
|
||||
Slapi_Entry *e = NULL, *pw_entry = NULL;
|
||||
- int type_name_disposition = 0;
|
||||
+ passwdPolicy *pwdpolicy = NULL;
|
||||
+ Slapi_Attr *attr = NULL;
|
||||
+ char *pwscheme_name = NULL;
|
||||
+ char *attr_name = NULL;
|
||||
char *actual_type_name = NULL;
|
||||
+ int type_name_disposition = 0;
|
||||
int attr_free_flags = 0;
|
||||
int rc = 0;
|
||||
- passwdPolicy *pwdpolicy = NULL;
|
||||
- struct pw_scheme *pwdscheme = NULL;
|
||||
- Slapi_Attr *attr;
|
||||
- char *attr_name;
|
||||
- Slapi_Value **sval;
|
||||
- slapdFrontendConfig_t *slapdFrontendConfig;
|
||||
int optype = -1;
|
||||
|
||||
/* If we already allocated a pw policy, return it */
|
||||
@@ -1717,9 +1717,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
pw_entry = get_entry(pb, bvp->bv_val);
|
||||
}
|
||||
}
|
||||
-
|
||||
slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
|
||||
-
|
||||
slapi_entry_free(e);
|
||||
|
||||
if (pw_entry == NULL) {
|
||||
@@ -1732,7 +1730,11 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
|
||||
/* Set the default values (from libglobs.c) */
|
||||
pwpolicy_init_defaults(pwdpolicy);
|
||||
- pwdpolicy->pw_storagescheme = slapdFrontendConfig->pw_storagescheme;
|
||||
+
|
||||
+ /* Set the current storage scheme */
|
||||
+ pwscheme_name = config_get_pw_storagescheme();
|
||||
+ pwdpolicy->pw_storagescheme = pw_name2scheme(pwscheme_name);
|
||||
+ slapi_ch_free_string(&pwscheme_name);
|
||||
|
||||
/* Set the defined values now */
|
||||
for (slapi_entry_first_attr(pw_entry, &attr); attr;
|
||||
@@ -1865,6 +1867,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn)
|
||||
}
|
||||
} else if (!strcasecmp(attr_name, "passwordstoragescheme")) {
|
||||
if ((sval = attr_get_present_values(attr))) {
|
||||
+ free_pw_scheme(pwdpolicy->pw_storagescheme);
|
||||
pwdpolicy->pw_storagescheme =
|
||||
pw_name2scheme((char *)slapi_value_get_string(*sval));
|
||||
}
|
||||
@@ -1924,10 +1927,9 @@ done:
|
||||
* structure from slapdFrontendconfig
|
||||
*/
|
||||
*pwdpolicy = slapdFrontendConfig->pw_policy;
|
||||
- pwdscheme = (struct pw_scheme *)slapi_ch_calloc(1, sizeof(struct pw_scheme));
|
||||
- *pwdscheme = *slapdFrontendConfig->pw_storagescheme;
|
||||
- pwdscheme->pws_name = strdup(slapdFrontendConfig->pw_storagescheme->pws_name);
|
||||
- pwdpolicy->pw_storagescheme = pwdscheme;
|
||||
+ pwscheme_name = config_get_pw_storagescheme();
|
||||
+ pwdpolicy->pw_storagescheme = pw_name2scheme(pwscheme_name);
|
||||
+ slapi_ch_free_string(&pwscheme_name);
|
||||
pwdpolicy->pw_admin = slapi_sdn_dup(slapdFrontendConfig->pw_policy.pw_admin);
|
||||
pw_get_admin_users(pwdpolicy);
|
||||
if (pb) {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,320 +0,0 @@
|
|||
From 656b141630c5f37a953a75ff05d3a1a30b14eef1 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 1 Feb 2018 14:28:24 -0500
|
||||
Subject: [PATCH] Ticket 49557 - Add config option for checking CRL on outbound
|
||||
SSL Connections
|
||||
|
||||
Bug Description: There are cases where a CRL is not available during an outbound
|
||||
replication connection. This is seen as an error by openldap,
|
||||
and the connection fails.
|
||||
|
||||
Fix Description: Add on/off option for checking the CRL. The default is not to
|
||||
check the CRL.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49557
|
||||
|
||||
Reviewed by: wibrown, Ludwig Krispenz, Thierry Bordaz
|
||||
---
|
||||
dirsrvtests/tests/suites/{ssl => tls}/__init__.py | 0
|
||||
dirsrvtests/tests/suites/tls/tls_check_crl_test.py | 52 +++++++++++++++++
|
||||
ldap/schema/01core389.ldif | 1 +
|
||||
ldap/servers/slapd/ldaputil.c | 9 ++-
|
||||
ldap/servers/slapd/libglobs.c | 66 +++++++++++++++++++++-
|
||||
ldap/servers/slapd/proto-slap.h | 2 +
|
||||
ldap/servers/slapd/slap.h | 10 +++-
|
||||
7 files changed, 135 insertions(+), 5 deletions(-)
|
||||
rename dirsrvtests/tests/suites/{ssl => tls}/__init__.py (100%)
|
||||
create mode 100644 dirsrvtests/tests/suites/tls/tls_check_crl_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/ssl/__init__.py b/dirsrvtests/tests/suites/tls/__init__.py
|
||||
similarity index 100%
|
||||
rename from dirsrvtests/tests/suites/ssl/__init__.py
|
||||
rename to dirsrvtests/tests/suites/tls/__init__.py
|
||||
diff --git a/dirsrvtests/tests/suites/tls/tls_check_crl_test.py b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py
|
||||
new file mode 100644
|
||||
index 000000000..8b4d07f94
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py
|
||||
@@ -0,0 +1,52 @@
|
||||
+# --- 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 pytest
|
||||
+import ldap
|
||||
+from lib389.topologies import topology_st
|
||||
+
|
||||
+def test_tls_check_crl(topology_st):
|
||||
+ """Test that TLS check_crl configurations work as expected.
|
||||
+
|
||||
+ :id:
|
||||
+ :steps:
|
||||
+ 1. Enable TLS
|
||||
+ 2. Set invalid value
|
||||
+ 3. Set valid values
|
||||
+ 4. Check config reset
|
||||
+ :expectedresults:
|
||||
+ 1. TlS is setup
|
||||
+ 2. The invalid value is rejected
|
||||
+ 3. The valid values are used
|
||||
+ 4. The value can be reset
|
||||
+ """
|
||||
+ standalone = topology_st.standalone
|
||||
+ # Enable TLS
|
||||
+ standalone.enable_tls()
|
||||
+ # Check all the valid values.
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none')
|
||||
+ with pytest.raises(ldap.OPERATIONS_ERROR):
|
||||
+ standalone.config.set('nsslapd-tls-check-crl', 'tnhoeutnoeutn')
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none')
|
||||
+
|
||||
+ standalone.config.set('nsslapd-tls-check-crl', 'peer')
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'peer')
|
||||
+
|
||||
+ standalone.config.set('nsslapd-tls-check-crl', 'none')
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none')
|
||||
+
|
||||
+ standalone.config.set('nsslapd-tls-check-crl', 'all')
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'all')
|
||||
+
|
||||
+ standalone.config.remove_all('nsslapd-tls-check-crl')
|
||||
+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none')
|
||||
+
|
||||
+
|
||||
+
|
||||
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
|
||||
index ab124c86c..c7f9fef2b 100644
|
||||
--- a/ldap/schema/01core389.ldif
|
||||
+++ b/ldap/schema/01core389.ldif
|
||||
@@ -304,6 +304,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2332 NAME 'allowWeakDHParam' DESC 'Netsc
|
||||
attributeTypes: ( 2.16.840.1.113730.3.1.2333 NAME 'nsds5ReplicaReleaseTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
|
||||
attributeTypes: ( 2.16.840.1.113730.3.1.2335 NAME 'nsds5ReplicaIgnoreMissingChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
|
||||
attributeTypes: ( 2.16.840.1.113730.3.1.2336 NAME 'nsDS5ReplicaBindDnGroupCheckInterval' DESC 'Replication configuration setting for controlling the bind dn group check interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
|
||||
+attributeTypes: ( 2.16.840.1.113730.3.1.2344 NAME 'nsslapd-tls-check-crl' DESC 'Check CRL when opening outbound TLS connections. Valid options are none, peer, all.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
|
||||
#
|
||||
# objectclasses
|
||||
#
|
||||
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
|
||||
index fa9d276a3..2fc2f0615 100644
|
||||
--- a/ldap/servers/slapd/ldaputil.c
|
||||
+++ b/ldap/servers/slapd/ldaputil.c
|
||||
@@ -570,6 +570,7 @@ slapi_ldif_parse_line(
|
||||
}
|
||||
|
||||
#if defined(USE_OPENLDAP)
|
||||
+
|
||||
static int
|
||||
setup_ol_tls_conn(LDAP *ld, int clientauth)
|
||||
{
|
||||
@@ -602,7 +603,13 @@ setup_ol_tls_conn(LDAP *ld, int clientauth)
|
||||
}
|
||||
}
|
||||
if (slapi_client_uses_openssl(ld)) {
|
||||
- const int crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
|
||||
+ int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
|
||||
+ tls_check_crl_t tls_check_state = config_get_tls_check_crl();
|
||||
+ if (tls_check_state == TLS_CHECK_PEER) {
|
||||
+ crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
|
||||
+ } else if (tls_check_state == TLS_CHECK_ALL) {
|
||||
+ crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
|
||||
+ }
|
||||
/* Sets the CRL evaluation strategy. */
|
||||
rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck);
|
||||
if (rc) {
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index c1a765aca..eb6552af1 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -157,7 +157,8 @@ typedef enum {
|
||||
CONFIG_STRING_OR_EMPTY, /* use an empty string */
|
||||
CONFIG_SPECIAL_ANON_ACCESS_SWITCH, /* maps strings to an enumeration */
|
||||
CONFIG_SPECIAL_VALIDATE_CERT_SWITCH, /* maps strings to an enumeration */
|
||||
- CONFIG_SPECIAL_UNHASHED_PW_SWITCH /* unhashed pw: on/off/nolog */
|
||||
+ CONFIG_SPECIAL_UNHASHED_PW_SWITCH, /* unhashed pw: on/off/nolog */
|
||||
+ CONFIG_SPECIAL_TLS_CHECK_CRL, /* maps enum tls_check_crl_t to char * */
|
||||
} ConfigVarType;
|
||||
|
||||
static int32_t config_set_onoff(const char *attrname, char *value, int32_t *configvalue, char *errorbuf, int apply);
|
||||
@@ -1173,7 +1174,15 @@ static struct config_get_and_set
|
||||
{CONFIG_LOGGING_BACKEND, NULL,
|
||||
log_set_backend, 0,
|
||||
(void **)&global_slapdFrontendConfig.logging_backend,
|
||||
- CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL}};
|
||||
+ CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL},
|
||||
+ {CONFIG_TLS_CHECK_CRL_ATTRIBUTE, config_set_tls_check_crl,
|
||||
+ NULL, 0,
|
||||
+ (void **)&global_slapdFrontendConfig.tls_check_crl,
|
||||
+ CONFIG_SPECIAL_TLS_CHECK_CRL, (ConfigGetFunc)config_get_tls_check_crl,
|
||||
+ "none" /* Allow reset to this value */}
|
||||
+
|
||||
+ /* End config */
|
||||
+ };
|
||||
|
||||
/*
|
||||
* hashNocaseString - used for case insensitive hash lookups
|
||||
@@ -1506,7 +1515,6 @@ FrontendConfig_init(void)
|
||||
cfg->maxdescriptors = SLAPD_DEFAULT_MAXDESCRIPTORS;
|
||||
cfg->groupevalnestlevel = SLAPD_DEFAULT_GROUPEVALNESTLEVEL;
|
||||
cfg->snmp_index = SLAPD_DEFAULT_SNMP_INDEX;
|
||||
-
|
||||
cfg->SSLclientAuth = SLAPD_DEFAULT_SSLCLIENTAUTH;
|
||||
|
||||
#ifdef USE_SYSCONF
|
||||
@@ -1524,6 +1532,7 @@ FrontendConfig_init(void)
|
||||
#endif
|
||||
init_security = cfg->security = LDAP_OFF;
|
||||
init_ssl_check_hostname = cfg->ssl_check_hostname = LDAP_ON;
|
||||
+ cfg->tls_check_crl = TLS_CHECK_NONE;
|
||||
init_return_exact_case = cfg->return_exact_case = LDAP_ON;
|
||||
init_result_tweak = cfg->result_tweak = LDAP_OFF;
|
||||
init_attrname_exceptions = cfg->attrname_exceptions = LDAP_OFF;
|
||||
@@ -2042,6 +2051,7 @@ config_set_port(const char *attrname, char *port, char *errorbuf, int apply)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
+
|
||||
int
|
||||
config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply)
|
||||
{
|
||||
@@ -2073,6 +2083,33 @@ config_set_secureport(const char *attrname, char *port, char *errorbuf, int appl
|
||||
}
|
||||
|
||||
|
||||
+int32_t
|
||||
+config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply)
|
||||
+{
|
||||
+ int32_t retVal = LDAP_SUCCESS;
|
||||
+ /* Default */
|
||||
+ tls_check_crl_t state = TLS_CHECK_NONE;
|
||||
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||
+
|
||||
+ if (strcasecmp(value, "none") == 0) {
|
||||
+ state = TLS_CHECK_NONE;
|
||||
+ } else if (strcasecmp(value, "peer") == 0) {
|
||||
+ state = TLS_CHECK_PEER;
|
||||
+ } else if (strcasecmp(value, "all") == 0) {
|
||||
+ state = TLS_CHECK_ALL;
|
||||
+ } else {
|
||||
+ retVal = LDAP_OPERATIONS_ERROR;
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: unsupported value: %s", attrname, value);
|
||||
+ }
|
||||
+
|
||||
+ if (retVal == LDAP_SUCCESS && apply) {
|
||||
+ slapi_atomic_store_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), state, __ATOMIC_RELEASE);
|
||||
+ }
|
||||
+
|
||||
+ return retVal;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int
|
||||
config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply)
|
||||
{
|
||||
@@ -4591,6 +4628,12 @@ config_set_versionstring(const char *attrname __attribute__((unused)), char *ver
|
||||
|
||||
#define config_copy_strval(s) s ? slapi_ch_strdup(s) : NULL;
|
||||
|
||||
+tls_check_crl_t
|
||||
+config_get_tls_check_crl() {
|
||||
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||
+ return (tls_check_crl_t)slapi_atomic_load_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), __ATOMIC_ACQUIRE);
|
||||
+}
|
||||
+
|
||||
int
|
||||
config_get_port()
|
||||
{
|
||||
@@ -7439,6 +7482,23 @@ config_set_value(
|
||||
slapi_entry_attr_set_int(e, cgas->attr_name, ival);
|
||||
break;
|
||||
|
||||
+ case CONFIG_SPECIAL_TLS_CHECK_CRL:
|
||||
+ if (!value) {
|
||||
+ slapi_entry_attr_set_charptr(e, cgas->attr_name, (char *)cgas->initvalue);
|
||||
+ break;
|
||||
+ }
|
||||
+ tls_check_crl_t state = *(tls_check_crl_t *)value;
|
||||
+
|
||||
+ if (state == TLS_CHECK_ALL) {
|
||||
+ sval = "all";
|
||||
+ } else if (state == TLS_CHECK_PEER) {
|
||||
+ sval = "peer";
|
||||
+ } else {
|
||||
+ sval = "none";
|
||||
+ }
|
||||
+ slapi_entry_attr_set_charptr(e, cgas->attr_name, sval);
|
||||
+ break;
|
||||
+
|
||||
case CONFIG_SPECIAL_SSLCLIENTAUTH:
|
||||
if (!value) {
|
||||
slapi_entry_attr_set_charptr(e, cgas->attr_name, "off");
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index 3b7ab53b2..b13334ad1 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -236,6 +236,7 @@ int config_set_port(const char *attrname, char *port, char *errorbuf, int apply)
|
||||
int config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply);
|
||||
int config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
int config_set_ssl_check_hostname(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
+int32_t config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
int config_set_SSL3ciphers(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
int config_set_localhost(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
int config_set_listenhost(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
@@ -397,6 +398,7 @@ void log_disable_hr_timestamps(void);
|
||||
|
||||
int config_get_SSLclientAuth(void);
|
||||
int config_get_ssl_check_hostname(void);
|
||||
+tls_check_crl_t config_get_tls_check_crl(void);
|
||||
char *config_get_SSL3ciphers(void);
|
||||
char *config_get_localhost(void);
|
||||
char *config_get_listenhost(void);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 216d94afd..443d90094 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -443,6 +443,13 @@ typedef void (*VFPV)(); /* takes undefined arguments */
|
||||
typedef int32_t slapi_onoff_t;
|
||||
typedef int32_t slapi_int_t;
|
||||
|
||||
+typedef enum _tls_check_crl_t {
|
||||
+ TLS_CHECK_NONE = 0,
|
||||
+ TLS_CHECK_PEER = 1,
|
||||
+ TLS_CHECK_ALL = 2,
|
||||
+} tls_check_crl_t;
|
||||
+
|
||||
+
|
||||
struct subfilt
|
||||
{
|
||||
char *sf_type;
|
||||
@@ -2151,6 +2158,7 @@ typedef struct _slapdEntryPoints
|
||||
#define CONFIG_RUNDIR_ATTRIBUTE "nsslapd-rundir"
|
||||
#define CONFIG_SSLCLIENTAUTH_ATTRIBUTE "nsslapd-SSLclientAuth"
|
||||
#define CONFIG_SSL_CHECK_HOSTNAME_ATTRIBUTE "nsslapd-ssl-check-hostname"
|
||||
+#define CONFIG_TLS_CHECK_CRL_ATTRIBUTE "nsslapd-tls-check-crl"
|
||||
#define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters"
|
||||
#define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout"
|
||||
#define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external"
|
||||
@@ -2263,6 +2271,7 @@ typedef struct _slapdFrontendConfig
|
||||
slapi_onoff_t security;
|
||||
int SSLclientAuth;
|
||||
slapi_onoff_t ssl_check_hostname;
|
||||
+ tls_check_crl_t tls_check_crl;
|
||||
int validate_cert;
|
||||
int sizelimit;
|
||||
int SNMPenabled;
|
||||
@@ -2294,7 +2303,6 @@ typedef struct _slapdFrontendConfig
|
||||
slapi_onoff_t plugin_track;
|
||||
slapi_onoff_t moddn_aci;
|
||||
struct pw_scheme *pw_storagescheme;
|
||||
-
|
||||
slapi_onoff_t pwpolicy_local;
|
||||
slapi_onoff_t pw_is_global_policy;
|
||||
slapi_onoff_t pwpolicy_inherit_global;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
From 10ec64288dcc25fd855bc05601bc4794ecea2003 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Tue, 6 Feb 2018 19:49:22 +0100
|
||||
Subject: [PATCH] Ticket 49560 - nsslapd-extract-pemfiles should be enabled by
|
||||
default as openldap is moving to openssl
|
||||
|
||||
Bug Description:
|
||||
Due to a change in the OpenLDAP client libraries (switching from NSS to OpenSSL),
|
||||
the TLS options LDAP_OPT_X_TLS_CACERTFILE, LDAP_OPT_X_TLS_KEYFILE, LDAP_OPT_X_TLS_CERTFILE,
|
||||
need to specify path to PEM files.
|
||||
|
||||
Those PEM files are extracted from the key/certs from the NSS db in /etc/dirsrv/slapd-xxx
|
||||
|
||||
Those files are extracted if the option (under 'cn=config') nsslapd-extract-pemfiles is set to 'on'.
|
||||
|
||||
The default value is 'off', that prevent secure outgoing connection.
|
||||
|
||||
Fix Description:
|
||||
|
||||
Enable nsslapd-extract-pemfiles by default
|
||||
Then when establishing an outgoing connection, if it is not using NSS crypto layer
|
||||
and the pem files have been extracted then use the PEM files
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49560
|
||||
|
||||
Reviewed by: mreynolds & mhonek
|
||||
|
||||
Platforms tested: RHEL 7.5
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
(cherry picked from commit 8304caec593b591558c9c18de9bcb6b2f23db5b6)
|
||||
---
|
||||
ldap/servers/slapd/ldaputil.c | 32 ++++++++++++++++----------------
|
||||
ldap/servers/slapd/libglobs.c | 2 +-
|
||||
ldap/servers/slapd/ssl.c | 2 +-
|
||||
3 files changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
|
||||
index 2fc2f0615..fcf22e632 100644
|
||||
--- a/ldap/servers/slapd/ldaputil.c
|
||||
+++ b/ldap/servers/slapd/ldaputil.c
|
||||
@@ -591,7 +591,7 @@ setup_ol_tls_conn(LDAP *ld, int clientauth)
|
||||
slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn",
|
||||
"failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength);
|
||||
}
|
||||
- if (slapi_client_uses_non_nss(ld)) {
|
||||
+ if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) {
|
||||
cacert = slapi_get_cacertfile();
|
||||
if (cacert) {
|
||||
/* CA Cert PEM file exists. Set the path to openldap option. */
|
||||
@@ -602,21 +602,21 @@ setup_ol_tls_conn(LDAP *ld, int clientauth)
|
||||
cacert, rc, ldap_err2string(rc));
|
||||
}
|
||||
}
|
||||
- if (slapi_client_uses_openssl(ld)) {
|
||||
- int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
|
||||
- tls_check_crl_t tls_check_state = config_get_tls_check_crl();
|
||||
- if (tls_check_state == TLS_CHECK_PEER) {
|
||||
- crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
|
||||
- } else if (tls_check_state == TLS_CHECK_ALL) {
|
||||
- crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
|
||||
- }
|
||||
- /* Sets the CRL evaluation strategy. */
|
||||
- rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck);
|
||||
- if (rc) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn",
|
||||
- "Could not set CRLCHECK [%d]: %d:%s\n",
|
||||
- crlcheck, rc, ldap_err2string(rc));
|
||||
- }
|
||||
+ }
|
||||
+ if (slapi_client_uses_openssl(ld)) {
|
||||
+ int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
|
||||
+ tls_check_crl_t tls_check_state = config_get_tls_check_crl();
|
||||
+ if (tls_check_state == TLS_CHECK_PEER) {
|
||||
+ crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
|
||||
+ } else if (tls_check_state == TLS_CHECK_ALL) {
|
||||
+ crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
|
||||
+ }
|
||||
+ /* Sets the CRL evaluation strategy. */
|
||||
+ rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck);
|
||||
+ if (rc) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn",
|
||||
+ "Could not set CRLCHECK [%d]: %d:%s\n",
|
||||
+ crlcheck, rc, ldap_err2string(rc));
|
||||
}
|
||||
}
|
||||
/* tell it where our cert db/file is */
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index eb6552af1..3bd5c1826 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -1688,7 +1688,7 @@ FrontendConfig_init(void)
|
||||
init_malloc_mmap_threshold = cfg->malloc_mmap_threshold = DEFAULT_MALLOC_UNSET;
|
||||
#endif
|
||||
|
||||
- init_extract_pem = cfg->extract_pem = LDAP_OFF;
|
||||
+ init_extract_pem = cfg->extract_pem = LDAP_ON;
|
||||
|
||||
/* Done, unlock! */
|
||||
CFG_UNLOCK_WRITE(cfg);
|
||||
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
|
||||
index 52ac7ea9f..36b09fd16 100644
|
||||
--- a/ldap/servers/slapd/ssl.c
|
||||
+++ b/ldap/servers/slapd/ssl.c
|
||||
@@ -2462,7 +2462,7 @@ slapd_SSL_client_auth(LDAP *ld)
|
||||
errorCode, slapd_pr_strerror(errorCode));
|
||||
} else {
|
||||
#if defined(USE_OPENLDAP)
|
||||
- if (slapi_client_uses_non_nss(ld)) {
|
||||
+ if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) {
|
||||
char *certdir = config_get_certdir();
|
||||
char *keyfile = NULL;
|
||||
char *certfile = NULL;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,286 +0,0 @@
|
|||
From 40fcaabfaa2c865471cc5fb1fab04106bc3ec611 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Thu, 18 Jan 2018 11:27:58 +1000
|
||||
Subject: [PATCH] Ticket bz1525628 - invalid password migration causes unauth
|
||||
bind
|
||||
|
||||
Bug Description: Slapi_ct_memcmp expects both inputs to be
|
||||
at LEAST size n. If they are not, we only compared UP to n.
|
||||
|
||||
Invalid migrations of passwords (IE {CRYPT}XX) would create
|
||||
a pw which is just salt and no hash. ct_memcmp would then
|
||||
only verify the salt bits and would allow the authentication.
|
||||
|
||||
This relies on an administrative mistake both of allowing
|
||||
password migration (nsslapd-allow-hashed-passwords) and then
|
||||
subsequently migrating an INVALID password to the server.
|
||||
|
||||
Fix Description: slapi_ct_memcmp now access n1, n2 size
|
||||
and will FAIL if they are not the same, but will still compare
|
||||
n bytes, where n is the "longest" memory, to the first byte
|
||||
of the other to prevent length disclosure of the shorter
|
||||
value (generally the mis-migrated password)
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1525628
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: ???
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
.../bz1525628_ct_memcmp_invalid_hash_test.py | 56 ++++++++++++++++++++++
|
||||
ldap/servers/plugins/pwdstorage/clear_pwd.c | 4 +-
|
||||
ldap/servers/plugins/pwdstorage/crypt_pwd.c | 4 +-
|
||||
ldap/servers/plugins/pwdstorage/md5_pwd.c | 4 +-
|
||||
ldap/servers/plugins/pwdstorage/sha_pwd.c | 16 +++++--
|
||||
ldap/servers/plugins/pwdstorage/smd5_pwd.c | 2 +-
|
||||
ldap/servers/slapd/ch_malloc.c | 36 ++++++++++++--
|
||||
ldap/servers/slapd/slapi-plugin.h | 2 +-
|
||||
8 files changed, 108 insertions(+), 16 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py
|
||||
new file mode 100644
|
||||
index 000000000..2f38384a1
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py
|
||||
@@ -0,0 +1,56 @@
|
||||
+# --- 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 ldap
|
||||
+import pytest
|
||||
+import logging
|
||||
+from lib389.topologies import topology_st
|
||||
+from lib389._constants import PASSWORD, DEFAULT_SUFFIX
|
||||
+
|
||||
+from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
|
||||
+
|
||||
+logging.getLogger(__name__).setLevel(logging.DEBUG)
|
||||
+log = logging.getLogger(__name__)
|
||||
+
|
||||
+def test_invalid_hash_fails(topology_st):
|
||||
+ """When given a malformed hash from userpassword migration
|
||||
+ slapi_ct_memcmp would check only to the length of the shorter
|
||||
+ field. This affects some values where it would ONLY verify
|
||||
+ the salt is valid, and thus would allow any password to bind.
|
||||
+
|
||||
+ :id: 8131c029-7147-47db-8d03-ec5db2a01cfb
|
||||
+ :setup: Standalone Instance
|
||||
+ :steps:
|
||||
+ 1. Create a user
|
||||
+ 2. Add an invalid password hash (truncated)
|
||||
+ 3. Attempt to bind
|
||||
+ :expectedresults:
|
||||
+ 1. User is added
|
||||
+ 2. Invalid pw hash is added
|
||||
+ 3. Bind fails
|
||||
+ """
|
||||
+ log.info("Running invalid hash test")
|
||||
+
|
||||
+ # Allow setting raw password hashes for migration.
|
||||
+ topology_st.standalone.config.set('nsslapd-allow-hashed-passwords', 'on')
|
||||
+
|
||||
+ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
|
||||
+ user = users.create(properties=TEST_USER_PROPERTIES)
|
||||
+ user.set('userPassword', '{CRYPT}XX')
|
||||
+
|
||||
+ # Attempt to bind. This should fail.
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ user.bind(PASSWORD)
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ user.bind('XX')
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ user.bind('{CRYPT}XX')
|
||||
+
|
||||
+ log.info("PASSED")
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/clear_pwd.c b/ldap/servers/plugins/pwdstorage/clear_pwd.c
|
||||
index f5e6f9d4c..3d340752d 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/clear_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/clear_pwd.c
|
||||
@@ -39,7 +39,7 @@ clear_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
* However, even if the first part of userpw matches dbpwd, but len !=, we
|
||||
* have already failed anyawy. This prevents substring matching.
|
||||
*/
|
||||
- if (slapi_ct_memcmp(userpwd, dbpwd, len_dbp) != 0) {
|
||||
+ if (slapi_ct_memcmp(userpwd, dbpwd, len_user, len_dbp) != 0) {
|
||||
result = 1;
|
||||
}
|
||||
} else {
|
||||
@@ -51,7 +51,7 @@ clear_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
* dbpwd to itself. We have already got result == 1 if we are here, so we are
|
||||
* just trying to take up time!
|
||||
*/
|
||||
- if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp)) {
|
||||
+ if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp, len_dbp)) {
|
||||
/* Do nothing, we have the if to fix a coverity check. */
|
||||
}
|
||||
}
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
index 3bd226581..0dccd1b51 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
@@ -65,13 +65,13 @@ crypt_close(Slapi_PBlock *pb __attribute__((unused)))
|
||||
int
|
||||
crypt_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
{
|
||||
- int rc;
|
||||
+ int32_t rc;
|
||||
char *cp;
|
||||
PR_Lock(cryptlock);
|
||||
/* we use salt (first 2 chars) of encoded password in call to crypt() */
|
||||
cp = crypt(userpwd, dbpwd);
|
||||
if (cp) {
|
||||
- rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd));
|
||||
+ rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd), strlen(cp));
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c
|
||||
index 1e2cf58e7..2c2aacaa6 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/md5_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c
|
||||
@@ -30,7 +30,7 @@
|
||||
int
|
||||
md5_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
{
|
||||
- int rc = -1;
|
||||
+ int32_t rc = -1;
|
||||
char *bver;
|
||||
PK11Context *ctx = NULL;
|
||||
unsigned int outLen;
|
||||
@@ -57,7 +57,7 @@ md5_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item);
|
||||
/* bver points to b2a_out upon success */
|
||||
if (bver) {
|
||||
- rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd));
|
||||
+ rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd), strlen(bver));
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME,
|
||||
"Could not base64 encode hashed value for password compare");
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c
|
||||
index 1fbe0bc82..381b31d7c 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c
|
||||
@@ -49,7 +49,7 @@ sha_pw_cmp(const char *userpwd, const char *dbpwd, unsigned int shaLen)
|
||||
char userhash[MAX_SHA_HASH_SIZE];
|
||||
char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3];
|
||||
char *dbhash = quick_dbhash;
|
||||
- struct berval salt;
|
||||
+ struct berval salt = {0};
|
||||
PRUint32 hash_len;
|
||||
unsigned int secOID;
|
||||
char *schemeName;
|
||||
@@ -122,9 +122,19 @@ sha_pw_cmp(const char *userpwd, const char *dbpwd, unsigned int shaLen)
|
||||
|
||||
/* the proof is in the comparison... */
|
||||
if (hash_len >= shaLen) {
|
||||
- result = slapi_ct_memcmp(userhash, dbhash, shaLen);
|
||||
+ /*
|
||||
+ * This say "if the hash has a salt IE >, OR if they are equal, check the hash component ONLY.
|
||||
+ * This is why we repeat shaLen twice, even though it seems odd. If you have a dbhast of ssha
|
||||
+ * it's len is 28, and the userpw is 20, but 0 - 20 is the sha, and 21-28 is the salt, which
|
||||
+ * has already been processed into userhash.
|
||||
+ * The case where dbpwd is truncated is handled above in "invalid base64" arm.
|
||||
+ */
|
||||
+ result = slapi_ct_memcmp(userhash, dbhash, shaLen, shaLen);
|
||||
} else {
|
||||
- result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, hash_len - OLD_SALT_LENGTH);
|
||||
+ /* This case is for if the salt is at the START, which only applies to DS40B1 case.
|
||||
+ * May never be a valid check...
|
||||
+ */
|
||||
+ result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, shaLen, hash_len - OLD_SALT_LENGTH);
|
||||
}
|
||||
|
||||
loser:
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
|
||||
index a83ac6fa4..cbfc74ff3 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
|
||||
@@ -82,7 +82,7 @@ smd5_pw_cmp(const char *userpwd, const char *dbpwd)
|
||||
PK11_DestroyContext(ctx, 1);
|
||||
|
||||
/* Compare everything up to the salt. */
|
||||
- rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH);
|
||||
+ rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH, MD5_LENGTH);
|
||||
|
||||
loser:
|
||||
if (dbhash && dbhash != quick_dbhash)
|
||||
diff --git a/ldap/servers/slapd/ch_malloc.c b/ldap/servers/slapd/ch_malloc.c
|
||||
index ef436b3e8..90a2b2c1a 100644
|
||||
--- a/ldap/servers/slapd/ch_malloc.c
|
||||
+++ b/ldap/servers/slapd/ch_malloc.c
|
||||
@@ -336,8 +336,8 @@ slapi_ch_smprintf(const char *fmt, ...)
|
||||
|
||||
/* Constant time memcmp. Does not shortcircuit on failure! */
|
||||
/* This relies on p1 and p2 both being size at least n! */
|
||||
-int
|
||||
-slapi_ct_memcmp(const void *p1, const void *p2, size_t n)
|
||||
+int32_t
|
||||
+slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2)
|
||||
{
|
||||
int result = 0;
|
||||
const unsigned char *_p1 = (const unsigned char *)p1;
|
||||
@@ -347,9 +347,35 @@ slapi_ct_memcmp(const void *p1, const void *p2, size_t n)
|
||||
return 2;
|
||||
}
|
||||
|
||||
- for (size_t i = 0; i < n; i++) {
|
||||
- if (_p1[i] ^ _p2[i]) {
|
||||
- result = 1;
|
||||
+ if (n1 == n2) {
|
||||
+ for (size_t i = 0; i < n1; i++) {
|
||||
+ if (_p1[i] ^ _p2[i]) {
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ const unsigned char *_pa;
|
||||
+ const unsigned char *_pb;
|
||||
+ size_t nl;
|
||||
+ if (n2 > n1) {
|
||||
+ _pa = _p2;
|
||||
+ _pb = _p2;
|
||||
+ nl = n2;
|
||||
+ } else {
|
||||
+ _pa = _p1;
|
||||
+ _pb = _p1;
|
||||
+ nl = n1;
|
||||
+ }
|
||||
+ /* We already fail as n1 != n2 */
|
||||
+ result = 3;
|
||||
+ for (size_t i = 0; i < nl; i++) {
|
||||
+ if (_pa[i] ^ _pb[i]) {
|
||||
+ /*
|
||||
+ * If we don't mutate result here, dead code elimination
|
||||
+ * we remove for loop.
|
||||
+ */
|
||||
+ result = 4;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
return result;
|
||||
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
||||
index 4566202d3..95cdcc0da 100644
|
||||
--- a/ldap/servers/slapd/slapi-plugin.h
|
||||
+++ b/ldap/servers/slapd/slapi-plugin.h
|
||||
@@ -5862,7 +5862,7 @@ char *slapi_ch_smprintf(const char *fmt, ...)
|
||||
* \param n length in bytes of the content of p1 AND p2.
|
||||
* \return 0 on match. 1 on non-match. 2 on presence of NULL pointer in p1 or p2.
|
||||
*/
|
||||
-int slapi_ct_memcmp(const void *p1, const void *p2, size_t n);
|
||||
+int32_t slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2);
|
||||
|
||||
/*
|
||||
* syntax plugin routines
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From 183517787fe86c1bc2359ad807318b8bca573d17 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 19 Jan 2018 16:34:36 +0100
|
||||
Subject: [PATCH] Ticket 49545 - final substring extended filter search returns
|
||||
invalid result
|
||||
|
||||
Bug Description:
|
||||
During a search (using extended filter with final substring), the server
|
||||
checks the filter before returning the matching entries.
|
||||
When checking the attribute value against the filter, it
|
||||
uses the wrong value.
|
||||
|
||||
Fix Description:
|
||||
Make suree it uses the right portion of the attribute value, in order
|
||||
to generate the keys to compare.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49545
|
||||
|
||||
Reviewed by: Ludwig Krispenz
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
ldap/servers/plugins/collation/orfilter.c | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c
|
||||
index a98d90219..672ee7b19 100644
|
||||
--- a/ldap/servers/plugins/collation/orfilter.c
|
||||
+++ b/ldap/servers/plugins/collation/orfilter.c
|
||||
@@ -182,17 +182,33 @@ ss_filter_match(or_filter_t * or, struct berval **vals)
|
||||
} else { /* final */
|
||||
auto size_t attempts = MAX_CHAR_COMBINING;
|
||||
auto char *limit = v.bv_val;
|
||||
+ auto char *end;
|
||||
auto struct berval **vkeys;
|
||||
auto struct berval *vals[2];
|
||||
auto struct berval key;
|
||||
+
|
||||
rc = -1;
|
||||
vals[0] = &v;
|
||||
vals[1] = NULL;
|
||||
key.bv_val = (*k)->bv_val;
|
||||
key.bv_len = (*k)->bv_len - 1;
|
||||
- v.bv_val = (*vals)->bv_val + (*vals)->bv_len;
|
||||
+ /* In the following lines it will loop to find
|
||||
+ * if the end of the attribute value matches the 'final' of the filter
|
||||
+ * Short summary:
|
||||
+ * vals contains the attribute value :for example "hello world"
|
||||
+ * key contain the key generated from the indexing of final part of the filter.
|
||||
+ * for example filter=(<attribut>=*ld), so key contains the indexing("ld").
|
||||
+ *
|
||||
+ * The loop will iterate over the attribute value (vals) from the end of string
|
||||
+ * to the begining. So it will try to index('d'), index('ld'), index('rld'), index('orld')...
|
||||
+ *
|
||||
+ * At each iteration if the key generated from indexing the portion of vals, matches
|
||||
+ * the key generate from the final part of the filter, then the loop stops => we are done
|
||||
+ */
|
||||
+ end = v.bv_val + v.bv_len - 1;
|
||||
+ v.bv_val = end;
|
||||
while (1) {
|
||||
- v.bv_len = (*vals)->bv_len - (v.bv_val - (*vals)->bv_val);
|
||||
+ v.bv_len = end - v.bv_val + 1;
|
||||
vkeys = ix->ix_index(ix, vals, NULL);
|
||||
if (vkeys && vkeys[0]) {
|
||||
auto const struct berval *vkey = vkeys[0];
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
From 233b64f26df76aa50f4b37aaf6b3804d208fdc1b Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Mon, 12 Feb 2018 09:24:25 +0100
|
||||
Subject: [PATCH] Ticket 49551 - v3 - correct handling of numsubordinates for
|
||||
cenotaphs and tombstone delete
|
||||
|
||||
Bug: The ticket exposed several problems with tombstone handling.
|
||||
- tombstone entries of conflicts were not purged in tombstone purging
|
||||
- cenotaphs are tombstone, but the subordinate count was not managed properly
|
||||
- direct delete of tombstones failed with err=1
|
||||
- delete of entry with only conflict children failed correctly, but gave no hint why
|
||||
|
||||
Fix: update the correct numsobordinates attribut for cenotaphs
|
||||
set proper flag in directly deleting a tombstone
|
||||
change search filter for tombstone purging to include ldapsubentries
|
||||
check for conflict children if a delete is rejected and add a message to the response
|
||||
|
||||
Reviewed by; Thierry, William - thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 14 +++++++++--
|
||||
ldap/servers/plugins/replication/urp.c | 8 +++---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 +++---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 14 ++++++++---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 3 ++-
|
||||
ldap/servers/slapd/back-ldbm/parents.c | 12 ++++++---
|
||||
ldap/servers/slapd/entry.c | 31 ++++++++++++++++++++++++
|
||||
ldap/servers/slapd/slapi-plugin.h | 2 ++
|
||||
ldap/servers/slapd/slapi-private.h | 1 +
|
||||
ldap/servers/slapd/task.c | 4 +--
|
||||
10 files changed, 78 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index bdb8a5167..628fb9ceb 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -3017,6 +3017,16 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data)
|
||||
search in the future, see _replica_reap_tombstones below and add more to the
|
||||
attrs array */
|
||||
deletion_csn = entry_get_deletion_csn(entry);
|
||||
+ if (deletion_csn == NULL) {
|
||||
+ /* this might be a tombstone which was directly added, eg a cenotaph
|
||||
+ * check if a tombstonecsn exist and use it
|
||||
+ */
|
||||
+ char *tombstonecsn = slapi_entry_attr_get_charptr(entry, SLAPI_ATTR_TOMBSTONE_CSN);
|
||||
+ if (tombstonecsn) {
|
||||
+ deletion_csn = csn_new_by_string(tombstonecsn);
|
||||
+ slapi_ch_free_string(&tombstonecsn);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if ((NULL == deletion_csn || csn_compare(deletion_csn, purge_csn) < 0) &&
|
||||
(!is_ruv_tombstone_entry(entry))) {
|
||||
@@ -3116,11 +3126,11 @@ _replica_reap_tombstones(void *arg)
|
||||
*/
|
||||
csn_as_string(purge_csn, PR_FALSE, deletion_csn_str);
|
||||
PR_snprintf(tombstone_filter, 128,
|
||||
- "(&(%s<=%s)(objectclass=nsTombstone))", SLAPI_ATTR_TOMBSTONE_CSN,
|
||||
+ "(&(%s<=%s)(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))", SLAPI_ATTR_TOMBSTONE_CSN,
|
||||
csn_as_string(purge_csn, PR_FALSE, deletion_csn_str));
|
||||
} else {
|
||||
/* Use the old inefficient filter */
|
||||
- PR_snprintf(tombstone_filter, 128, "(objectclass=nsTombstone)");
|
||||
+ PR_snprintf(tombstone_filter, 128, "(&(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))");
|
||||
}
|
||||
|
||||
/* we just need the objectclass - for the deletion csn
|
||||
diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c
|
||||
index d4556d7fd..11c5da7cf 100644
|
||||
--- a/ldap/servers/plugins/replication/urp.c
|
||||
+++ b/ldap/servers/plugins/replication/urp.c
|
||||
@@ -911,7 +911,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
|
||||
cenotaph,
|
||||
NULL,
|
||||
repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
|
||||
- OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP);
|
||||
+ OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY);
|
||||
slapi_add_internal_pb(add_pb);
|
||||
slapi_pblock_get(add_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
|
||||
|
||||
@@ -1922,7 +1922,7 @@ done:
|
||||
newpb = NULL;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_REPL, sessionid,
|
||||
- "urp_get_min_naming_conflict_entry - Found %d entries\n", i);
|
||||
+ "urp_get_min_naming_conflict_entry - Found %d entries\n", min_csn?1:0);
|
||||
|
||||
return min_naming_conflict_entry;
|
||||
}
|
||||
@@ -2172,8 +2172,8 @@ mod_objectclass_attr(const char *uniqueid, const Slapi_DN *entrysdn, const Slapi
|
||||
char csnstr[CSN_STRSIZE+1] = {0};
|
||||
|
||||
slapi_mods_init(&smods, 3);
|
||||
- slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry");
|
||||
- slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", CSN_STRSIZE, csn_as_string(opcsn, PR_FALSE, csnstr));
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_ADD, "objectclass", "ldapsubentry");
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "conflictcsn", csn_as_string(opcsn, PR_FALSE, csnstr));
|
||||
op_result = urp_fixup_modify_entry(uniqueid, entrysdn, opcsn, &smods, 0);
|
||||
slapi_mods_done(&smods);
|
||||
if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) {
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
index c93d44a65..f0a3262ec 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
||||
@@ -81,6 +81,7 @@ ldbm_back_add(Slapi_PBlock *pb)
|
||||
Slapi_Operation *operation;
|
||||
int is_replicated_operation = 0;
|
||||
int is_resurect_operation = 0;
|
||||
+ int is_cenotaph_operation = 0;
|
||||
int is_tombstone_operation = 0;
|
||||
int is_fixup_operation = 0;
|
||||
int is_remove_from_cache = 0;
|
||||
@@ -116,6 +117,7 @@ ldbm_back_add(Slapi_PBlock *pb)
|
||||
}
|
||||
|
||||
is_resurect_operation = operation_is_flag_set(operation, OP_FLAG_RESURECT_ENTRY);
|
||||
+ is_cenotaph_operation = operation_is_flag_set(operation, OP_FLAG_CENOTAPH_ENTRY);
|
||||
is_tombstone_operation = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY);
|
||||
is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP);
|
||||
is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
|
||||
@@ -846,9 +848,9 @@ ldbm_back_add(Slapi_PBlock *pb)
|
||||
the in-memory state of the parent to reflect the new child (update
|
||||
subordinate count specifically */
|
||||
if (parententry) {
|
||||
- retval = parent_update_on_childchange(&parent_modify_c,
|
||||
- is_resurect_operation ? PARENTUPDATE_RESURECT : PARENTUPDATE_ADD,
|
||||
- NULL);
|
||||
+ int op = is_resurect_operation ? PARENTUPDATE_RESURECT : PARENTUPDATE_ADD;
|
||||
+ if (is_cenotaph_operation ) op |= PARENTUPDATE_CREATE_TOMBSTONE;
|
||||
+ retval = parent_update_on_childchange(&parent_modify_c, op, NULL);
|
||||
slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_add",
|
||||
"conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n",
|
||||
conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval);
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
index be0db1bd0..bc0a3654e 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
||||
@@ -291,9 +291,16 @@ replace_entry:
|
||||
retval = slapi_entry_has_children(e->ep_entry);
|
||||
if (retval && !is_replicated_operation) {
|
||||
ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF;
|
||||
- slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
|
||||
- "conn=%lu op=%d Deleting entry %s has %d children.\n",
|
||||
- conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval);
|
||||
+ if (slapi_entry_has_conflict_children(e->ep_entry, (void *)li->li_identity) > 0) {
|
||||
+ ldap_result_message = "Entry has replication conflicts as children";
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
|
||||
+ "conn=%lu op=%d Deleting entry %s has replication conflicts as children.\n",
|
||||
+ conn_id, op_id, slapi_entry_get_dn(e->ep_entry));
|
||||
+ } else {
|
||||
+ slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
|
||||
+ "conn=%lu op=%d Deleting entry %s has %d children.\n",
|
||||
+ conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval);
|
||||
+ }
|
||||
retval = -1;
|
||||
goto error_return;
|
||||
}
|
||||
@@ -431,6 +438,7 @@ replace_entry:
|
||||
slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_delete",
|
||||
"Attempt to Tombstone again a tombstone entry %s\n", dn);
|
||||
delete_tombstone_entry = 1;
|
||||
+ operation_set_flag(operation, OP_FLAG_TOMBSTONE_ENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
||||
index b41a2d241..5797dd779 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
||||
@@ -2824,7 +2824,8 @@ _entryrdn_delete_key(backend *be,
|
||||
break;
|
||||
}
|
||||
childelem = (rdn_elem *)dataret.data;
|
||||
- if (!slapi_is_special_rdn(childelem->rdn_elem_nrdn_rdn, RDN_IS_TOMBSTONE)) {
|
||||
+ if (!slapi_is_special_rdn(childelem->rdn_elem_nrdn_rdn, RDN_IS_TOMBSTONE) &&
|
||||
+ !strcasestr(childelem->rdn_elem_nrdn_rdn, "cenotaphid")) {
|
||||
/* there's at least one live child */
|
||||
slapi_log_err(SLAPI_LOG_ERR, "_entryrdn_delete_key",
|
||||
"Failed to remove %s; has a child %s\n", nrdn,
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/parents.c b/ldap/servers/slapd/back-ldbm/parents.c
|
||||
index 79e66451e..1afc795c0 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/parents.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/parents.c
|
||||
@@ -89,7 +89,11 @@ parent_update_on_childchange(modify_context *mc, int op, size_t *new_sub_count)
|
||||
}
|
||||
}
|
||||
|
||||
- if (PARENTUPDATE_DELETE_TOMBSTONE != repl_op) {
|
||||
+ if ((PARENTUPDATE_ADD == op) && (PARENTUPDATE_CREATE_TOMBSTONE == repl_op)) {
|
||||
+ /* we are directly adding a tombstone entry, only need to
|
||||
+ * update the tombstone subordinates
|
||||
+ */
|
||||
+ } else if (PARENTUPDATE_DELETE_TOMBSTONE != repl_op) {
|
||||
/* are we adding ? */
|
||||
if (((PARENTUPDATE_ADD == op) || (PARENTUPDATE_RESURECT == op)) && !already_present) {
|
||||
/* If so, and the parent entry does not already have a subcount
|
||||
@@ -136,10 +140,10 @@ parent_update_on_childchange(modify_context *mc, int op, size_t *new_sub_count)
|
||||
}
|
||||
}
|
||||
|
||||
- /* tombstoneNumSubordinates is needed only when this is repl op
|
||||
- * and a child is being deleted */
|
||||
+ /* tombstoneNumSubordinates has to be updated if a tombstone child has been
|
||||
+ * deleted or a tombstone has been directly added (cenotaph) */
|
||||
current_sub_count = LDAP_MAXINT;
|
||||
- if ((repl_op && (PARENTUPDATE_DEL == op)) || (PARENTUPDATE_RESURECT == op)) {
|
||||
+ if (repl_op) {
|
||||
ret = slapi_entry_attr_find(mc->old_entry->ep_entry,
|
||||
tombstone_numsubordinates, &read_attr);
|
||||
if (0 == ret) {
|
||||
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
|
||||
index 32828b4e2..b85e9f5b0 100644
|
||||
--- a/ldap/servers/slapd/entry.c
|
||||
+++ b/ldap/servers/slapd/entry.c
|
||||
@@ -3238,6 +3238,37 @@ slapi_entry_has_children(const Slapi_Entry *entry)
|
||||
return slapi_entry_has_children_ext(entry, 0);
|
||||
}
|
||||
|
||||
+int
|
||||
+slapi_entry_has_conflict_children(const Slapi_Entry *entry, void *plg_id)
|
||||
+{
|
||||
+ Slapi_PBlock *search_pb = NULL;
|
||||
+ Slapi_Entry **entries;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ search_pb = slapi_pblock_new();
|
||||
+ slapi_search_internal_set_pb(search_pb, slapi_entry_get_dn_const(entry),
|
||||
+ LDAP_SCOPE_ONELEVEL,
|
||||
+ "(&(objectclass=ldapsubentry)(nsds5ReplConflict=namingConflict*))",
|
||||
+ NULL, 0, NULL, NULL, plg_id, 0);
|
||||
+ slapi_search_internal_pb(search_pb);
|
||||
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
||||
+ if (rc) {
|
||||
+ rc = -1;
|
||||
+ } else {
|
||||
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
|
||||
+ if (entries && entries[0]) {
|
||||
+ /* we found at least one conflict entry */
|
||||
+ rc = 1;
|
||||
+ } else {
|
||||
+ rc = 0;
|
||||
+ }
|
||||
+ slapi_free_search_results_internal(search_pb);
|
||||
+ }
|
||||
+ slapi_pblock_destroy(search_pb);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Renames an entry to simulate a MODRDN operation
|
||||
*/
|
||||
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
||||
index 95cdcc0da..6978e258f 100644
|
||||
--- a/ldap/servers/slapd/slapi-plugin.h
|
||||
+++ b/ldap/servers/slapd/slapi-plugin.h
|
||||
@@ -2000,6 +2000,8 @@ int slapi_entry_has_children(const Slapi_Entry *e);
|
||||
*/
|
||||
int slapi_entry_has_children_ext(const Slapi_Entry *e, int include_tombstone);
|
||||
|
||||
+int slapi_entry_has_conflict_children(const Slapi_Entry *e, void *plg_id);
|
||||
+
|
||||
/**
|
||||
* This function determines if an entry is the root DSE.
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
||||
index 548d5cabb..b08c0d7ce 100644
|
||||
--- a/ldap/servers/slapd/slapi-private.h
|
||||
+++ b/ldap/servers/slapd/slapi-private.h
|
||||
@@ -403,6 +403,7 @@ char *slapi_filter_to_string_internal(const struct slapi_filter *f, char *buf, s
|
||||
#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x000800 */
|
||||
#define OP_FLAG_TOMBSTONE_ENTRY SLAPI_OP_FLAG_TOMBSTONE_ENTRY /* 0x001000 */
|
||||
#define OP_FLAG_RESURECT_ENTRY 0x002000
|
||||
+#define OP_FLAG_CENOTAPH_ENTRY 0x004000
|
||||
#define OP_FLAG_ACTION_NOLOG 0x008000 /* Do not log the entry in \
|
||||
* audit log or change log \
|
||||
*/
|
||||
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
|
||||
index 4bd8895ff..3f9d5d995 100644
|
||||
--- a/ldap/servers/slapd/task.c
|
||||
+++ b/ldap/servers/slapd/task.c
|
||||
@@ -2352,10 +2352,10 @@ task_fixup_tombstone_thread(void *arg)
|
||||
|
||||
if (task_data->stripcsn) {
|
||||
/* find tombstones with nsTombstoneCSN */
|
||||
- filter = "(&(nstombstonecsn=*)(objectclass=nsTombstone))";
|
||||
+ filter = "(&(nstombstonecsn=*)(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))";
|
||||
} else {
|
||||
/* find tombstones missing nsTombstoneCSN */
|
||||
- filter = "(&(!(nstombstonecsn=*))(objectclass=nsTombstone))";
|
||||
+ filter = "(&(!(nstombstonecsn=*))(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))";
|
||||
}
|
||||
|
||||
/* Okay check the specified backends only */
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
From a88eea7e06a8e0a7367b2d266f9db37f6d5bbb4a Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Mon, 12 Feb 2018 16:27:03 +0100
|
||||
Subject: [PATCH] Ticket 49551 - fix memory leak found by coverity
|
||||
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index 628fb9ceb..e3ddd783d 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -3002,6 +3002,7 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data)
|
||||
if the value is set in the replica, we will know about it immediately */
|
||||
PRBool *tombstone_reap_stop = ((reap_callback_data *)cb_data)->tombstone_reap_stop;
|
||||
const CSN *deletion_csn = NULL;
|
||||
+ int deletion_csn_free = 0;
|
||||
int rc = -1;
|
||||
|
||||
/* abort reaping if we've been told to stop or we're shutting down */
|
||||
@@ -3024,6 +3025,7 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data)
|
||||
char *tombstonecsn = slapi_entry_attr_get_charptr(entry, SLAPI_ATTR_TOMBSTONE_CSN);
|
||||
if (tombstonecsn) {
|
||||
deletion_csn = csn_new_by_string(tombstonecsn);
|
||||
+ deletion_csn_free = 1;
|
||||
slapi_ch_free_string(&tombstonecsn);
|
||||
}
|
||||
}
|
||||
@@ -3056,6 +3058,9 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data)
|
||||
/* Don't update the count for the database tombstone entry */
|
||||
(*num_entriesp)++;
|
||||
}
|
||||
+ if (deletion_csn_free) {
|
||||
+ csn_free(&deletion_csn);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
From 7d5ae77d840afda65020237f87a4535f09f0b462 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 29 Mar 2018 13:24:47 -0400
|
||||
Subject: [PATCH] Ticket 48184 - revert previous patch around unuc-stans
|
||||
shutdown crash
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48184
|
||||
---
|
||||
ldap/servers/slapd/conntable.c | 13 --------
|
||||
ldap/servers/slapd/daemon.c | 76 +++++++++++++++++-------------------------
|
||||
ldap/servers/slapd/fe.h | 1 -
|
||||
ldap/servers/slapd/slap.h | 1 -
|
||||
4 files changed, 30 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||
index f2f763dfa..7c57b47cd 100644
|
||||
--- a/ldap/servers/slapd/conntable.c
|
||||
+++ b/ldap/servers/slapd/conntable.c
|
||||
@@ -91,19 +91,6 @@ connection_table_abandon_all_operations(Connection_Table *ct)
|
||||
}
|
||||
}
|
||||
|
||||
-void
|
||||
-connection_table_disconnect_all(Connection_Table *ct)
|
||||
-{
|
||||
- for (size_t i = 0; i < ct->size; i++) {
|
||||
- if (ct->c[i].c_mutex) {
|
||||
- Connection *c = &(ct->c[i]);
|
||||
- PR_EnterMonitor(c->c_mutex);
|
||||
- disconnect_server_nomutex(c, c->c_connid, -1, SLAPD_DISCONNECT_ABORT, ECANCELED);
|
||||
- PR_ExitMonitor(c->c_mutex);
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* Given a file descriptor for a socket, this function will return
|
||||
* a slot in the connection table to use.
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index c245a4d4e..fcc461a90 100644
|
||||
--- a/ldap/servers/slapd/daemon.c
|
||||
+++ b/ldap/servers/slapd/daemon.c
|
||||
@@ -1176,30 +1176,6 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
|
||||
housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
|
||||
disk_monitoring_stop();
|
||||
|
||||
- /*
|
||||
- * Now that they are abandonded, we need to mark them as done.
|
||||
- * In NS while it's safe to allow excess jobs to be cleaned by
|
||||
- * by the walk and ns_job_done of remaining queued events, the
|
||||
- * issue is that if we allow something to live past this point
|
||||
- * the CT is freed from underneath, and bad things happen (tm).
|
||||
- *
|
||||
- * NOTE: We do this after we stop psearch, because there could
|
||||
- * be a race between flagging the psearch done, and users still
|
||||
- * try to send on the connection. Similar with op_threads.
|
||||
- */
|
||||
- connection_table_disconnect_all(the_connection_table);
|
||||
-
|
||||
- /*
|
||||
- * WARNING: Normally we should close the tp in main
|
||||
- * but because of issues in the current connection design
|
||||
- * we need to close it here to guarantee events won't fire!
|
||||
- *
|
||||
- * All the connection close jobs "should" complete before
|
||||
- * shutdown at least.
|
||||
- */
|
||||
- ns_thrpool_shutdown(tp);
|
||||
- ns_thrpool_wait(tp);
|
||||
-
|
||||
threads = g_get_active_threadcnt();
|
||||
if (threads > 0) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "slapd_daemon",
|
||||
@@ -1652,18 +1628,25 @@ ns_handle_closure(struct ns_job_t *job)
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
int do_yield = 0;
|
||||
|
||||
+/* this function must be called from the event loop thread */
|
||||
+#ifdef DEBUG
|
||||
+ PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
+#else
|
||||
+ /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
+ if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ns_handle_closure", "Attempt to close outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
+ c->c_connid, c->c_sd);
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
PR_EnterMonitor(c->c_mutex);
|
||||
- /* Assert we really have the right job state. */
|
||||
- PR_ASSERT(job == c->c_job);
|
||||
|
||||
connection_release_nolock_ext(c, 1); /* release ref acquired for event framework */
|
||||
PR_ASSERT(c->c_ns_close_jobs == 1); /* should be exactly 1 active close job - this one */
|
||||
c->c_ns_close_jobs--; /* this job is processing closure */
|
||||
- /* Because handle closure will add a new job, we need to detach our current one. */
|
||||
- c->c_job = NULL;
|
||||
do_yield = ns_handle_closure_nomutex(c);
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
- /* Remove this task now. */
|
||||
ns_job_done(job);
|
||||
if (do_yield) {
|
||||
/* closure not done - another reference still outstanding */
|
||||
@@ -1686,14 +1669,6 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Cancel any existing ns jobs we have registered.
|
||||
- */
|
||||
- if (conn->c_job != NULL) {
|
||||
- ns_job_done(conn->c_job);
|
||||
- conn->c_job = NULL;
|
||||
- }
|
||||
-
|
||||
if (CONN_NEEDS_CLOSING(conn)) {
|
||||
/* there should only ever be 0 or 1 active closure jobs */
|
||||
PR_ASSERT((conn->c_ns_close_jobs == 0) || (conn->c_ns_close_jobs == 1));
|
||||
@@ -1703,10 +1678,13 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
conn->c_connid, conn->c_sd);
|
||||
return;
|
||||
} else {
|
||||
+ /* just make sure we schedule the event to be closed in a timely manner */
|
||||
+ tv.tv_sec = 0;
|
||||
+ tv.tv_usec = slapd_wakeup_timer * 1000;
|
||||
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 */
|
||||
- /* Close the job asynchronously. Why? */
|
||||
- ns_result_t job_result = ns_add_job(conn->c_tp, NS_JOB_TIMER, ns_handle_closure, conn, &(conn->c_job));
|
||||
+ ns_result_t job_result = ns_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
|
||||
+ ns_handle_closure, conn, NULL);
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post closure job "
|
||||
@@ -1750,7 +1728,7 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
#endif
|
||||
ns_result_t job_result = ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
|
||||
NS_JOB_READ | NS_JOB_PRESERVE_FD,
|
||||
- ns_handle_pr_read_ready, conn, &(conn->c_job));
|
||||
+ ns_handle_pr_read_ready, conn, NULL);
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
@@ -1779,12 +1757,19 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
int maxthreads = config_get_maxthreadsperconn();
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
|
||||
- PR_EnterMonitor(c->c_mutex);
|
||||
- /* Assert we really have the right job state. */
|
||||
- PR_ASSERT(job == c->c_job);
|
||||
+/* this function must be called from the event loop thread */
|
||||
+#ifdef DEBUG
|
||||
+ PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
+#else
|
||||
+ /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
+ if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "Attempt to handle read ready outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
+ c->c_connid, c->c_sd);
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
- /* On all code paths we remove the job, so set it null now */
|
||||
- c->c_job = NULL;
|
||||
+ PR_EnterMonitor(c->c_mutex);
|
||||
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "activity on conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
@@ -1844,7 +1829,6 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "queued conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
}
|
||||
- /* Since we call done on the job, we need to remove it here. */
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
ns_job_done(job);
|
||||
return;
|
||||
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
|
||||
index f47bb6145..4d25a9fb8 100644
|
||||
--- a/ldap/servers/slapd/fe.h
|
||||
+++ b/ldap/servers/slapd/fe.h
|
||||
@@ -100,7 +100,6 @@ extern Connection_Table *the_connection_table; /* JCM - Exported from globals.c
|
||||
Connection_Table *connection_table_new(int table_size);
|
||||
void connection_table_free(Connection_Table *ct);
|
||||
void connection_table_abandon_all_operations(Connection_Table *ct);
|
||||
-void connection_table_disconnect_all(Connection_Table *ct);
|
||||
Connection *connection_table_get_connection(Connection_Table *ct, int sd);
|
||||
int connection_table_move_connection_out_of_active_list(Connection_Table *ct, Connection *c);
|
||||
void connection_table_move_connection_on_to_active_list(Connection_Table *ct, Connection *c);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 443d90094..9b10aa19e 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1651,7 +1651,6 @@ 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 */
|
||||
int c_ns_close_jobs; /* number of current close jobs */
|
||||
char *c_ipaddr; /* ip address str - used by monitor */
|
||||
} Connection;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
From d606691d341dfffee0b02fc55fb29f74f975e775 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 21 Mar 2018 18:26:16 +0100
|
||||
Subject: [PATCH] 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
|
||||
---
|
||||
ldap/servers/slapd/csngen.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
|
||||
index 287ea847e..4ac45acf0 100644
|
||||
--- a/ldap/servers/slapd/csngen.c
|
||||
+++ b/ldap/servers/slapd/csngen.c
|
||||
@@ -331,7 +331,7 @@ 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
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 293361f34d935080c1d8d0e73b4355b48faebe2a Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Tue, 27 Feb 2018 13:56:14 +0100
|
||||
Subject: [PATCH] Ticket 49161 - memberof fails if group is moved into scope
|
||||
|
||||
if the DEL part of the replace of memberof fails because it does not exist
|
||||
just add the new memberof values
|
||||
|
||||
Reviwed by: Mark, thanks
|
||||
---
|
||||
ldap/servers/plugins/memberof/memberof.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index fcfa7817d..2f46167dc 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -1710,6 +1710,13 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_o
|
||||
replace_mod.mod_values = replace_val;
|
||||
}
|
||||
rc = memberof_add_memberof_attr(mods, op_to, config->auto_add_oc);
|
||||
+ if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
|
||||
+ /* the memberof values to be replaced do not exist
|
||||
+ * just add the new values */
|
||||
+ mods[0] = mods[1];
|
||||
+ mods[1] = NULL;
|
||||
+ rc = memberof_add_memberof_attr(mods, op_to, config->auto_add_oc);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
From dd12327d1523f3ff9d6ae8b44b640fb9d0d2d53b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 19 Feb 2018 10:44:36 -0500
|
||||
Subject: [PATCH] Ticket 49296 - Fix race condition in connection code with
|
||||
anonymous limits
|
||||
|
||||
Bug Description: When a connection first comes in we set the anonymous
|
||||
resource limits (if set) before we do anything else. The
|
||||
way we check if the connection is "new" was flawed. It
|
||||
assumed the connection was new if no operations were
|
||||
completed yet, but there was a small window between sending
|
||||
the result and setting that the operation completed in the
|
||||
connection struct.
|
||||
|
||||
So on a connection that binds and then does a search, when
|
||||
the server sends the bind result the client sends the search,
|
||||
but the search op/activity can be picked up before we set
|
||||
c_opscompleted. This opens a window where the code thinks
|
||||
the search op is the first op(new connection), and it incorrectly
|
||||
sets the anonymous limits for the bind dn.
|
||||
|
||||
Fix description: Do not use c_opscompleted to determine if a connection is new,
|
||||
instead use a new flag to set the connection "initialized",
|
||||
which prevents the race condition.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49296
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 0d5214d08e6b5b39fb9d5ef5cf3d8834574954f1)
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 12 +++++++++++-
|
||||
ldap/servers/slapd/slap.h | 7 +++----
|
||||
2 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 5d2b64ed2..5ca32a333 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -217,6 +217,7 @@ connection_cleanup(Connection *conn)
|
||||
conn->c_connid = 0;
|
||||
conn->c_opsinitiated = 0;
|
||||
conn->c_opscompleted = 0;
|
||||
+ conn->c_anonlimits_set = 0;
|
||||
conn->c_threadnumber = 0;
|
||||
conn->c_refcnt = 0;
|
||||
conn->c_idlesince = 0;
|
||||
@@ -1549,7 +1550,9 @@ connection_threadmain()
|
||||
g_decr_active_threadcnt();
|
||||
return;
|
||||
}
|
||||
- if (pb_conn->c_opscompleted == 0) {
|
||||
+
|
||||
+ PR_EnterMonitor(pb_conn->c_mutex);
|
||||
+ if (pb_conn->c_anonlimits_set == 0) {
|
||||
/*
|
||||
* We have a new connection, set the anonymous reslimit idletimeout
|
||||
* if applicable.
|
||||
@@ -1568,7 +1571,14 @@ connection_threadmain()
|
||||
}
|
||||
}
|
||||
slapi_ch_free_string(&anon_dn);
|
||||
+ /*
|
||||
+ * Set connection as initialized to avoid setting anonymous limits
|
||||
+ * multiple times on the same connection
|
||||
+ */
|
||||
+ pb_conn->c_anonlimits_set = 1;
|
||||
}
|
||||
+ PR_ExitMonitor(pb_conn->c_mutex);
|
||||
+
|
||||
if (connection_call_io_layer_callbacks(pb_conn)) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain",
|
||||
"Could not add/remove IO layers from connection\n");
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 9b10aa19e..03355f5fe 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1616,6 +1616,7 @@ typedef struct conn
|
||||
PRUint64 c_maxthreadsblocked; /* # of operations blocked by maxthreads */
|
||||
int c_opsinitiated; /* # ops initiated/next op id */
|
||||
PRInt32 c_opscompleted; /* # ops completed */
|
||||
+ uint64_t c_anonlimits_set; /* default anon limits are set */
|
||||
PRInt32 c_threadnumber; /* # threads used in this conn */
|
||||
int c_refcnt; /* # ops refering to this conn */
|
||||
PRMonitor *c_mutex; /* protect each conn structure; need to be re-entrant */
|
||||
@@ -1623,10 +1624,8 @@ typedef struct conn
|
||||
time_t c_idlesince; /* last time of activity on conn */
|
||||
int c_idletimeout; /* local copy of idletimeout */
|
||||
int c_idletimeout_handle; /* the resource limits handle */
|
||||
- Conn_private *c_private; /* data which is not shared outside*/
|
||||
- /* connection.c */
|
||||
- int c_flags; /* Misc flags used only for SSL */
|
||||
- /* status currently */
|
||||
+ Conn_private *c_private; /* data which is not shared outside connection.c */
|
||||
+ int c_flags; /* Misc flags used only for SSL status currently */
|
||||
int c_needpw; /* need new password */
|
||||
CERTCertificate *c_client_cert; /* Client's Cert */
|
||||
PRFileDesc *c_prfd; /* NSPR 2.1 FileDesc */
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
From 3dac3503087b6bae9e6e3d63a8214e8be65a145b Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 19 Jan 2018 17:50:59 +0100
|
||||
Subject: [PATCH 05/10] Ticket 49540 - Indexing task is reported finished too
|
||||
early regarding the backend status
|
||||
|
||||
Bug Description:
|
||||
If a task complete successfully, its status is updated before the backend
|
||||
can receive update.
|
||||
|
||||
Fix Description:
|
||||
postpone the task status update after backend is reenabled
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49540
|
||||
|
||||
Reviewed by: Ludwig Krispenz
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49540_test.py | 135 ++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 16 +--
|
||||
2 files changed, 145 insertions(+), 6 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49540_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49540_test.py b/dirsrvtests/tests/tickets/ticket49540_test.py
|
||||
new file mode 100644
|
||||
index 000000000..1fbfde2c5
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49540_test.py
|
||||
@@ -0,0 +1,135 @@
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import ldap
|
||||
+import time
|
||||
+import re
|
||||
+from lib389._constants import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES
|
||||
+from lib389 import Entry
|
||||
+
|
||||
+
|
||||
+
|
||||
+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__)
|
||||
+
|
||||
+HOMEDIRECTORY_INDEX = 'cn=homeDirectory,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
|
||||
+HOMEDIRECTORY_CN = "homedirectory"
|
||||
+MATCHINGRULE = 'nsMatchingRule'
|
||||
+USER_CN = 'user_'
|
||||
+
|
||||
+def create_index_entry(topo):
|
||||
+ log.info("\n\nindex homeDirectory")
|
||||
+ try:
|
||||
+ ent = topo.getEntry(HOMEDIRECTORY_INDEX, ldap.SCOPE_BASE)
|
||||
+ except ldap.NO_SUCH_OBJECT:
|
||||
+ topo.add_s(Entry((HOMEDIRECTORY_INDEX, {
|
||||
+ 'objectclass': "top nsIndex".split(),
|
||||
+ 'cn': HOMEDIRECTORY_CN,
|
||||
+ 'nsSystemIndex': 'false',
|
||||
+ MATCHINGRULE: ['caseIgnoreIA5Match', 'caseExactIA5Match' ],
|
||||
+ 'nsIndexType': ['eq', 'sub', 'pres']})))
|
||||
+
|
||||
+
|
||||
+def provision_users(topo):
|
||||
+ test_users = []
|
||||
+ homeValue = b'x' * (32 * 1024) # just to slow down indexing
|
||||
+ for i in range(100):
|
||||
+ CN = '%s%d' % (USER_CN, i)
|
||||
+ users = UserAccounts(topo, SUFFIX)
|
||||
+ user_props = TEST_USER_PROPERTIES.copy()
|
||||
+ user_props.update({'uid': CN, 'cn': CN, 'sn': '_%s' % CN, HOMEDIRECTORY_CN: homeValue})
|
||||
+ testuser = users.create(properties=user_props)
|
||||
+ test_users.append(testuser)
|
||||
+ return test_users
|
||||
+
|
||||
+def start_start_status(server):
|
||||
+ args = {TASK_WAIT: False}
|
||||
+ indexTask = Tasks(server)
|
||||
+ indexTask.reindex(suffix=SUFFIX, attrname='homeDirectory', args=args)
|
||||
+ return indexTask
|
||||
+
|
||||
+def check_task_status(server, indexTask, test_entry):
|
||||
+ finish_pattern = re.compile(".*Finished indexing.*")
|
||||
+ mod = [(ldap.MOD_REPLACE, 'sn', b'foo')]
|
||||
+ for i in range(10):
|
||||
+ log.info("check_task_status =========> %d th loop" % i)
|
||||
+ try:
|
||||
+ ent = server.getEntry(indexTask.dn, ldap.SCOPE_BASE)
|
||||
+ if ent.hasAttr('nsTaskStatus'):
|
||||
+ value = str(ent.getValue('nsTaskStatus'))
|
||||
+ finish = finish_pattern.search(value)
|
||||
+ log.info("%s ---> %s" % (indexTask.dn, value))
|
||||
+ else:
|
||||
+ finish = None
|
||||
+ log.info("%s ---> NO STATUS" % (indexTask.dn))
|
||||
+
|
||||
+ if not finish:
|
||||
+ # This is not yet finished try an update
|
||||
+ try:
|
||||
+ server.modify_s(test_entry, mod)
|
||||
+
|
||||
+ # weird, may be indexing just complete
|
||||
+ ent = server.getEntry(indexTask.dn, ldap.SCOPE_BASE, ['nsTaskStatus'])
|
||||
+ assert (ent.hasAttr('nsTaskStatus') and regex.search(ent.getValue('nsTaskStatus')))
|
||||
+ log.info("Okay, it just finished so the MOD was successful")
|
||||
+ except ldap.UNWILLING_TO_PERFORM:
|
||||
+ log.info("=========> Great it was expected in the middle of index")
|
||||
+ else:
|
||||
+ # The update should be successful
|
||||
+ server.modify_s(test_entry, mod)
|
||||
+
|
||||
+ except ldap.NO_SUCH_OBJECT:
|
||||
+ log.info("%s: no found" % (indexTask.dn))
|
||||
+
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+def test_ticket49540(topo):
|
||||
+ """Specify a test case purpose or name here
|
||||
+
|
||||
+ :id: 1df16d5a-1b92-46b7-8435-876b87545748
|
||||
+ :setup: Standalone Instance
|
||||
+ :steps:
|
||||
+ 1. Create homeDirectory index (especially with substring)
|
||||
+ 2. Creates 100 users with large homeDirectory value => long to index
|
||||
+ 3. Start an indexing task WITHOUT waiting for its completion
|
||||
+ 4. Monitor that until task.status = 'Finish', any update -> UNWILLING to perform
|
||||
+ :expectedresults:
|
||||
+ 1. Index configuration succeeds
|
||||
+ 2. users entry are successfully created
|
||||
+ 3. Indexing task is started
|
||||
+ 4. If the task.status does not contain 'Finished indexing', any update should return UNWILLING_TO_PERFORM
|
||||
+ When it contains 'Finished indexing', updates should be successful
|
||||
+ """
|
||||
+
|
||||
+ server = topo.standalone
|
||||
+ create_index_entry(server)
|
||||
+ test_users = provision_users(server)
|
||||
+
|
||||
+ indexTask = start_start_status(server)
|
||||
+ check_task_status(server, indexTask, test_users[0].dn)
|
||||
+
|
||||
+ # If you need any test suite initialization,
|
||||
+ # please, write additional fixture for that (including finalizer).
|
||||
+ # Topology for suites are predefined in lib389/topologies.py.
|
||||
+
|
||||
+ # If you need host, port or any other data about instance,
|
||||
+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
|
||||
+
|
||||
+ if DEBUGGING:
|
||||
+ # Add debugging steps(if any)...
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+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/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
index 4347c1721..16b87ee6b 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
@@ -2562,12 +2562,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
|
||||
vlvIndex_go_online(pvlv[vlvidx], be);
|
||||
}
|
||||
|
||||
- if (task) {
|
||||
- slapi_task_log_status(task, "%s: Finished indexing.",
|
||||
- inst->inst_name);
|
||||
- slapi_task_log_notice(task, "%s: Finished indexing.",
|
||||
- inst->inst_name);
|
||||
- }
|
||||
+ /* if it was a task, its status will be updated later after backend is ready for update */
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ldbm_back_ldbm2index", "%s: Finished indexing.\n",
|
||||
inst->inst_name);
|
||||
return_value = 0; /* success */
|
||||
@@ -2591,6 +2586,15 @@ err_min:
|
||||
dblayer_release_id2entry(be, db); /* nope */
|
||||
instance_set_not_busy(inst);
|
||||
|
||||
+ if (return_value == 0) {
|
||||
+ if (task) {
|
||||
+ slapi_task_log_status(task, "%s: Finished indexing.",
|
||||
+ inst->inst_name);
|
||||
+ slapi_task_log_notice(task, "%s: Finished indexing.",
|
||||
+ inst->inst_name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (run_from_cmdline) {
|
||||
dblayer_instance_close(be);
|
||||
if (0 != dblayer_close(li, DBLAYER_INDEX_MODE)) {
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
From 22cf575ae7aea204c3e3974c645725a25f4e09e6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 14 Feb 2018 20:25:34 -0500
|
||||
Subject: [PATCH] Ticket 49566 - ds-replcheck needs to work with hidden
|
||||
conflict entries
|
||||
|
||||
Description: Conflict entries are now hidden and the tool needs to account
|
||||
for it. The filter needs to include "objectclass=ldapsubentry"
|
||||
|
||||
Added option to prompt for password, and cleaned up man page.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49566
|
||||
|
||||
Reviewed by: spichugi(Thanks!)
|
||||
|
||||
(cherry picked from commit 9e2009ae7105dda5493d4d60b20f15ffb369ab26)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-replcheck | 23 ++++++++++++++++-------
|
||||
man/man1/ds-replcheck.1 | 14 +++++++++++---
|
||||
2 files changed, 27 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||||
index 0b7e70ee8..45c4670a3 100755
|
||||
--- a/ldap/admin/src/scripts/ds-replcheck
|
||||
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||||
@@ -14,6 +14,7 @@ import time
|
||||
import ldap
|
||||
import ldapurl
|
||||
import argparse
|
||||
+import getpass
|
||||
|
||||
from ldap.ldapobject import SimpleLDAPObject
|
||||
from ldap.cidict import cidict
|
||||
@@ -878,14 +879,16 @@ def do_online_report(opts, output_file=None):
|
||||
controls = [paged_ctrl]
|
||||
req_pr_ctrl = controls[0]
|
||||
try:
|
||||
- master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE, "objectclass=*",
|
||||
+ master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'],
|
||||
serverctrls=controls)
|
||||
except ldap.LDAPError as e:
|
||||
print("Error: Failed to get Master entries: %s", str(e))
|
||||
exit(1)
|
||||
try:
|
||||
- replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE, "objectclass=*",
|
||||
+ replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'],
|
||||
serverctrls=controls)
|
||||
except ldap.LDAPError as e:
|
||||
@@ -928,7 +931,8 @@ def do_online_report(opts, output_file=None):
|
||||
if m_pctrls[0].cookie:
|
||||
# Copy cookie from response control to request control
|
||||
req_pr_ctrl.cookie = m_pctrls[0].cookie
|
||||
- master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE, "objectclass=*",
|
||||
+ master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'], serverctrls=controls)
|
||||
else:
|
||||
m_done = True # No more pages available
|
||||
@@ -947,7 +951,8 @@ def do_online_report(opts, output_file=None):
|
||||
if r_pctrls[0].cookie:
|
||||
# Copy cookie from response control to request control
|
||||
req_pr_ctrl.cookie = r_pctrls[0].cookie
|
||||
- replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE, "objectclass=*",
|
||||
+ replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'], serverctrls=controls)
|
||||
else:
|
||||
r_done = True # No more pages available
|
||||
@@ -976,8 +981,9 @@ def main():
|
||||
parser = argparse.ArgumentParser(description=desc)
|
||||
parser.add_argument('-v', '--verbose', help='Verbose output', action='store_true', default=False, dest='verbose')
|
||||
parser.add_argument('-o', '--outfile', help='The output file', dest='file', default=None)
|
||||
- parser.add_argument('-D', '--binddn', help='The Bind DN', dest='binddn', default="")
|
||||
- parser.add_argument('-w', '--bindpw', help='The Bind password', dest='bindpw', default="")
|
||||
+ parser.add_argument('-D', '--binddn', help='The Bind DN', dest='binddn', default=None)
|
||||
+ parser.add_argument('-w', '--bindpw', help='The Bind password', dest='bindpw', default=None)
|
||||
+ parser.add_argument('-W', '--prompt', help='Prompt for the bind password', action='store_true', dest='prompt', default=False)
|
||||
parser.add_argument('-m', '--master_url', help='The LDAP URL for the Master server (REQUIRED)',
|
||||
dest='murl', default=None)
|
||||
parser.add_argument('-r', '--replica_url', help='The LDAP URL for the Replica server (REQUIRED)',
|
||||
@@ -1012,7 +1018,7 @@ def main():
|
||||
elif (args.mldif is None and
|
||||
(args.suffix is None or
|
||||
args.binddn is None or
|
||||
- args.bindpw is None or
|
||||
+ (args.bindpw is None and args.prompt is False) or
|
||||
args.murl is None or
|
||||
args.rurl is None)):
|
||||
print("\n-------> Missing required options for online mode!\n")
|
||||
@@ -1098,6 +1104,9 @@ def main():
|
||||
print("Can't open file: " + args.file)
|
||||
exit(1)
|
||||
|
||||
+ if args.prompt:
|
||||
+ opts['bindpw'] = getpass.getpass('Enter password:')
|
||||
+
|
||||
if opts['mldif'] is not None and opts['rldif'] is not None:
|
||||
print ("Performing offline report...")
|
||||
do_offline_report(opts, OUTPUT_FILE)
|
||||
diff --git a/man/man1/ds-replcheck.1 b/man/man1/ds-replcheck.1
|
||||
index 21b4802a5..3f14e11c8 100644
|
||||
--- a/man/man1/ds-replcheck.1
|
||||
+++ b/man/man1/ds-replcheck.1
|
||||
@@ -2,7 +2,7 @@
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
-.TH DS-REPLCHECK 1 "May 2, 2017"
|
||||
+.TH DS-REPLCHECK 1 "Feb 14, 2018"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@@ -19,7 +19,7 @@
|
||||
ds-replcheck - Performs replication synchronization report between two replicas
|
||||
|
||||
.SH SYNOPSIS
|
||||
-ds-replcheck [-h] [-o FILE] [-D BINDDN] [-w BINDPW] [-m MURL]
|
||||
+ds-replcheck [-h] [-o FILE] [-D BINDDN] [[-w BINDPW] [-W]] [-m MURL]
|
||||
[-r RURL] [-b SUFFIX] [-l LAG] [-Z CERTDIR]
|
||||
[-i IGNORE] [-p PAGESIZE] [-M MLDIF] [-R RLDIF]
|
||||
|
||||
@@ -41,6 +41,10 @@ The Directory Manager DN, or root DN.a (online mode)
|
||||
.B \fB\-w\fR \fIPASSWORD\fR
|
||||
The Directory Manager password (online mode)
|
||||
.TP
|
||||
+.B \fB\-W\fR
|
||||
+.br
|
||||
+Prompt for the Directory Manager password (online mode)
|
||||
+.TP
|
||||
.B \fB\-m\fR \fILDAP_URL\fR
|
||||
The LDAP Url for the first replica (online mode)
|
||||
.TP
|
||||
@@ -59,6 +63,10 @@ The directory containing a certificate database for StartTLS/SSL connections. (
|
||||
.B \fB\-i\fR \fIIGNORE LIST\fR
|
||||
Comma separated list of attributes to ignore in the report (online & offline)
|
||||
.TP
|
||||
+.B \fB\-c\fR
|
||||
+.br
|
||||
+Display verbose conflict entry information
|
||||
+.TP
|
||||
.B \fB\-M\fR \fILDIF FILE\fR
|
||||
The LDIF file for the first replica (offline mode)
|
||||
.TP
|
||||
@@ -81,5 +89,5 @@ ds-replcheck was written by the 389 Project.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to https://pagure.io/389-ds-base/new_issue
|
||||
.SH COPYRIGHT
|
||||
-Copyright \(co 2017 Red Hat, Inc.
|
||||
+Copyright \(co 2018 Red Hat, Inc.
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
From a0c4a8d69735cb37e5b52b195ec632ce6d1f028f Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Tue, 21 Nov 2017 17:23:29 +0100
|
||||
Subject: [PATCH] Ticket 49460 - replica_write_ruv log a failure even when it
|
||||
succeeds
|
||||
|
||||
Bug Description:
|
||||
Minor issue
|
||||
If the update of the DB RUV returns a success LDAP_SUCCESS (internal modify),
|
||||
it however logs an error as if it failed
|
||||
|
||||
side effect of https://pagure.io/389-ds-base/issue/48118
|
||||
|
||||
Fix Description:
|
||||
Log a message only on failure
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49460
|
||||
|
||||
Reviewed by: Ludwig Krispenz, William Brown
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49460_test.py | 115 +++++++++++++++++++++++
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 3 +-
|
||||
2 files changed, 116 insertions(+), 2 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49460_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49460_test.py b/dirsrvtests/tests/tickets/ticket49460_test.py
|
||||
new file mode 100644
|
||||
index 000000000..296b3c9aa
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49460_test.py
|
||||
@@ -0,0 +1,115 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+import os
|
||||
+import re
|
||||
+from lib389._constants import *
|
||||
+from lib389.config import Config
|
||||
+from lib389 import DirSrv, Entry
|
||||
+from lib389.topologies import topology_m3 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__)
|
||||
+
|
||||
+USER_CN="user"
|
||||
+
|
||||
+def add_user(server, no, desc='dummy', sleep=True):
|
||||
+ cn = '%s%d' % (USER_CN, no)
|
||||
+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
|
||||
+ log.fatal('Adding user (%s): ' % dn)
|
||||
+ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser', 'userSecurityInformation'],
|
||||
+ 'sn': ['_%s' % cn],
|
||||
+ 'description': [desc]})))
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+def check_user(server, no, timeout=10):
|
||||
+
|
||||
+ cn = '%s%d' % (USER_CN, no)
|
||||
+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
|
||||
+ found = False
|
||||
+ cpt = 0
|
||||
+ while cpt < timeout:
|
||||
+ try:
|
||||
+ server.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
|
||||
+ found = True
|
||||
+ break
|
||||
+ except ldap.NO_SUCH_OBJECT:
|
||||
+ time.sleep(1)
|
||||
+ cpt += 1
|
||||
+ return found
|
||||
+
|
||||
+def pattern_errorlog(server, log_pattern):
|
||||
+ file_obj = open(server.errlog, "r")
|
||||
+
|
||||
+ found = None
|
||||
+ # Use a while true iteration because 'for line in file: hit a
|
||||
+ while True:
|
||||
+ line = file_obj.readline()
|
||||
+ found = log_pattern.search(line)
|
||||
+ if ((line == '') or (found)):
|
||||
+ break
|
||||
+
|
||||
+ return found
|
||||
+
|
||||
+def test_ticket_49460(topo):
|
||||
+ """Specify a test case purpose or name here
|
||||
+
|
||||
+ :id: d1aa2e8b-e6ab-4fc6-9c63-c6f622544f2d
|
||||
+ :setup: Fill in set up configuration here
|
||||
+ :steps:
|
||||
+ 1. Enable replication logging
|
||||
+ 2. Do few updates to generatat RUV update
|
||||
+ :expectedresults:
|
||||
+ 1. No report of failure when the RUV is updated
|
||||
+ """
|
||||
+
|
||||
+ M1 = topo.ms["master1"]
|
||||
+ M2 = topo.ms["master2"]
|
||||
+ M3 = topo.ms["master3"]
|
||||
+
|
||||
+ for i in (M1, M2, M3):
|
||||
+ i.config.loglevel(vals=[256 + 4], service='access')
|
||||
+ i.config.loglevel(vals=[LOG_REPLICA, LOG_DEFAULT], service='error')
|
||||
+
|
||||
+ add_user(M1, 11, desc="add to M1")
|
||||
+ add_user(M2, 21, desc="add to M2")
|
||||
+ add_user(M3, 31, desc="add to M3")
|
||||
+
|
||||
+ for i in (M1, M2, M3):
|
||||
+ assert check_user(i, 11)
|
||||
+ assert check_user(i, 21)
|
||||
+ assert check_user(i, 31)
|
||||
+
|
||||
+ time.sleep(10)
|
||||
+
|
||||
+ #M1.tasks.cleanAllRUV(suffix=SUFFIX, replicaid='3',
|
||||
+ # force=False, args={TASK_WAIT: True})
|
||||
+ #time.sleep(10)
|
||||
+ regex = re.compile(".*Failed to update RUV tombstone.*LDAP error - 0")
|
||||
+ assert not pattern_errorlog(M1, regex)
|
||||
+ assert not pattern_errorlog(M2, regex)
|
||||
+ assert not pattern_errorlog(M3, regex)
|
||||
+
|
||||
+ # If you need any test suite initialization,
|
||||
+ # please, write additional fixture for that (including finalizer).
|
||||
+ # Topology for suites are predefined in lib389/topologies.py.
|
||||
+
|
||||
+ # If you need host, port or any other data about instance,
|
||||
+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
|
||||
+
|
||||
+ if DEBUGGING:
|
||||
+ # Add debugging steps(if any)...
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index e3ddd783d..c6d6ee746 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -2829,8 +2829,7 @@ replica_write_ruv(Replica *r)
|
||||
/* this includes an internal operation - but since this only happens
|
||||
during server startup - its ok that we have lock around it */
|
||||
rc = _replica_configure_ruv(r, PR_TRUE);
|
||||
- } else /* error */
|
||||
- {
|
||||
+ } else if (rc != LDAP_SUCCESS) { /* error */
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"replica_write_ruv - Failed to update RUV tombstone for %s; "
|
||||
"LDAP error - %d\n",
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 9c929dbfcd1687ba43b2b2ee649c0e6522365fad Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Wed, 4 Apr 2018 08:59:15 +0200
|
||||
Subject: [PATCH] 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
|
||||
---
|
||||
ldap/servers/slapd/csngen.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
|
||||
index 4ac45acf0..3afc9176b 100644
|
||||
--- a/ldap/servers/slapd/csngen.c
|
||||
+++ b/ldap/servers/slapd/csngen.c
|
||||
@@ -338,7 +338,11 @@ csngen_adjust_time(CSNGen *gen, const CSN *csn)
|
||||
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",
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
From 71b87e678bcc03bb9a0802f7dffc97cf354ee69a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 5 Apr 2018 14:52:34 -0400
|
||||
Subject: [PATCH] CVE-2018-1089 - Crash from long search filter
|
||||
|
||||
---
|
||||
ldap/servers/slapd/filter.c | 8 ++++----
|
||||
ldap/servers/slapd/util.c | 10 +++++-----
|
||||
2 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/filter.c b/ldap/servers/slapd/filter.c
|
||||
index 2ac3d2cd8..393a4dcee 100644
|
||||
--- 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);
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
|
||||
index ddb2cc899..cb46efb3d 100644
|
||||
--- 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;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
From e4d51884e3ca36b8256c33936dc31e77e0ad4736 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 8 May 2018 12:35:43 -0400
|
||||
Subject: [PATCH] Ticket 49649
|
||||
|
||||
Description: Fix crpyt.h include
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49649
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
|
||||
(cherry picked from commit 2817f0c49401056835a79aafd8f8d4edc9113d1d)
|
||||
---
|
||||
ldap/servers/plugins/pwdstorage/crypt_pwd.c | 10 +---------
|
||||
1 file changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
index 0dccd1b51..19894bd80 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
|
||||
@@ -20,15 +20,7 @@
|
||||
#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 */
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
From a13a83465c685d6ec8d47b6f10646986ded16a68 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 9 May 2018 16:36:48 -0400
|
||||
Subject: [PATCH] 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)
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif | 12 ++++++++++++
|
||||
2 files changed, 13 insertions(+)
|
||||
create mode 100644 ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 8834a7819..055d480aa 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -949,6 +949,7 @@ 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/50contentsync.ldif \
|
||||
ldap/admin/src/scripts/60upgradeschemafiles.pl \
|
||||
ldap/admin/src/scripts/60upgradeconfigfiles.pl \
|
||||
diff --git a/ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif b/ldap/admin/src/scripts/50pbkdf2pwdstorageplugin.ldif
|
||||
new file mode 100644
|
||||
index 000000000..462d5534a
|
||||
--- /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
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
From 1c077cff1ce49f5380192325a6947c623019c365 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 9 May 2018 16:39:23 -0400
|
||||
Subject: [PATCH] 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)
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
.../admin/src/scripts/50cryptpwdstorageplugin.ldif | 38 ++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
create mode 100644 ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 055d480aa..4f62a899b 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -950,6 +950,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
|
||||
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 \
|
||||
diff --git a/ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif b/ldap/admin/src/scripts/50cryptpwdstorageplugin.ldif
|
||||
new file mode 100644
|
||||
index 000000000..0a4a50776
|
||||
--- /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
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
From 279489884f56cfc97d1ad9afdf92da3ad3b05b70 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 11 May 2018 10:53:06 -0400
|
||||
Subject: [PATCH] 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)
|
||||
---
|
||||
.../tests/suites/replication/cascading_test.py | 150 +++++++++++++++++++++
|
||||
ldap/servers/plugins/replication/repl5_plugins.c | 10 ++
|
||||
2 files changed, 160 insertions(+)
|
||||
create mode 100644 dirsrvtests/tests/suites/replication/cascading_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/replication/cascading_test.py b/dirsrvtests/tests/suites/replication/cascading_test.py
|
||||
new file mode 100644
|
||||
index 000000000..7331f20e9
|
||||
--- /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])
|
||||
+
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
index 0aee8829a..324e38263 100644
|
||||
--- 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 ||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From f0b41ec12f957612c69ae5be3bbbb6e2d6db2530 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Thu, 17 May 2018 10:31:58 +0200
|
||||
Subject: [PATCH] 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
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 5ca32a333..b5030f0cb 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -1822,9 +1822,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) {
|
||||
/*
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
From 5a5d3dffd0b36edb543fd31fa53d7128dd5161c2 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 18 May 2018 10:13:46 +0200
|
||||
Subject: [PATCH] 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)
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 2 +
|
||||
ldap/servers/slapd/conntable.c | 13 ++++
|
||||
ldap/servers/slapd/daemon.c | 131 ++++++++++++++++++++++++++++------------
|
||||
ldap/servers/slapd/fe.h | 1 +
|
||||
ldap/servers/slapd/slap.h | 1 +
|
||||
5 files changed, 108 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index b5030f0cb..76e83112b 100644
|
||||
--- 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();
|
||||
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||
index 7c57b47cd..f2f763dfa 100644
|
||||
--- a/ldap/servers/slapd/conntable.c
|
||||
+++ b/ldap/servers/slapd/conntable.c
|
||||
@@ -91,6 +91,19 @@ connection_table_abandon_all_operations(Connection_Table *ct)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+connection_table_disconnect_all(Connection_Table *ct)
|
||||
+{
|
||||
+ for (size_t i = 0; i < ct->size; i++) {
|
||||
+ if (ct->c[i].c_mutex) {
|
||||
+ Connection *c = &(ct->c[i]);
|
||||
+ PR_EnterMonitor(c->c_mutex);
|
||||
+ disconnect_server_nomutex(c, c->c_connid, -1, SLAPD_DISCONNECT_ABORT, ECANCELED);
|
||||
+ PR_ExitMonitor(c->c_mutex);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Given a file descriptor for a socket, this function will return
|
||||
* a slot in the connection table to use.
|
||||
*
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index fcc461a90..50e67474e 100644
|
||||
--- 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 {
|
||||
@@ -1176,6 +1182,32 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
|
||||
housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
|
||||
disk_monitoring_stop();
|
||||
|
||||
+ /*
|
||||
+ * Now that they are abandonded, we need to mark them as done.
|
||||
+ * In NS while it's safe to allow excess jobs to be cleaned by
|
||||
+ * by the walk and ns_job_done of remaining queued events, the
|
||||
+ * issue is that if we allow something to live past this point
|
||||
+ * the CT is freed from underneath, and bad things happen (tm).
|
||||
+ *
|
||||
+ * NOTE: We do this after we stop psearch, because there could
|
||||
+ * be a race between flagging the psearch done, and users still
|
||||
+ * try to send on the connection. Similar with op_threads.
|
||||
+ */
|
||||
+ connection_table_disconnect_all(the_connection_table);
|
||||
+
|
||||
+ /*
|
||||
+ * WARNING: Normally we should close the tp in main
|
||||
+ * but because of issues in the current connection design
|
||||
+ * we need to close it here to guarantee events won't fire!
|
||||
+ *
|
||||
+ * All the connection close jobs "should" complete before
|
||||
+ * shutdown at least.
|
||||
+ */
|
||||
+ if (enable_nunc_stans) {
|
||||
+ ns_thrpool_shutdown(tp);
|
||||
+ ns_thrpool_wait(tp);
|
||||
+ }
|
||||
+
|
||||
threads = g_get_active_threadcnt();
|
||||
if (threads > 0) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "slapd_daemon",
|
||||
@@ -1628,25 +1660,18 @@ ns_handle_closure(struct ns_job_t *job)
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
int do_yield = 0;
|
||||
|
||||
-/* this function must be called from the event loop thread */
|
||||
-#ifdef DEBUG
|
||||
- PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
-#else
|
||||
- /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
- if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_closure", "Attempt to close outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
- c->c_connid, c->c_sd);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
PR_EnterMonitor(c->c_mutex);
|
||||
+ /* Assert we really have the right job state. */
|
||||
+ PR_ASSERT(job == c->c_job);
|
||||
|
||||
connection_release_nolock_ext(c, 1); /* release ref acquired for event framework */
|
||||
PR_ASSERT(c->c_ns_close_jobs == 1); /* should be exactly 1 active close job - this one */
|
||||
c->c_ns_close_jobs--; /* this job is processing closure */
|
||||
+ /* Because handle closure will add a new job, we need to detach our current one. */
|
||||
+ c->c_job = NULL;
|
||||
do_yield = ns_handle_closure_nomutex(c);
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
+ /* Remove this task now. */
|
||||
ns_job_done(job);
|
||||
if (do_yield) {
|
||||
/* closure not done - another reference still outstanding */
|
||||
@@ -1659,14 +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) {
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
if (CONN_NEEDS_CLOSING(conn)) {
|
||||
@@ -1676,15 +1712,12 @@ 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 {
|
||||
- /* just make sure we schedule the event to be closed in a timely manner */
|
||||
- tv.tv_sec = 0;
|
||||
- tv.tv_usec = slapd_wakeup_timer * 1000;
|
||||
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 */
|
||||
- ns_result_t job_result = ns_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
|
||||
- ns_handle_closure, conn, NULL);
|
||||
+ /* Close the job asynchronously. Why? */
|
||||
+ ns_result_t job_result = ns_add_job(conn->c_tp, NS_JOB_TIMER, ns_handle_closure, conn, &(conn->c_job));
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post closure job "
|
||||
@@ -1723,12 +1756,12 @@ 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,
|
||||
NS_JOB_READ | NS_JOB_PRESERVE_FD,
|
||||
- ns_handle_pr_read_ready, conn, NULL);
|
||||
+ ns_handle_pr_read_ready, conn, &(conn->c_job));
|
||||
if (job_result != NS_SUCCESS) {
|
||||
if (job_result == NS_SHUTDOWN) {
|
||||
slapi_log_err(SLAPI_LOG_INFO, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
@@ -1745,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
|
||||
@@ -1757,19 +1812,12 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
int maxthreads = config_get_maxthreadsperconn();
|
||||
Connection *c = (Connection *)ns_job_get_data(job);
|
||||
|
||||
-/* this function must be called from the event loop thread */
|
||||
-#ifdef DEBUG
|
||||
- PR_ASSERT(0 == NS_JOB_IS_THREAD(ns_job_get_type(job)));
|
||||
-#else
|
||||
- /* This doesn't actually confirm it's in the event loop thread, but it's a start */
|
||||
- if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "Attempt to handle read ready outside of event loop thread %" PRIu64 " for fd=%d\n",
|
||||
- c->c_connid, c->c_sd);
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
PR_EnterMonitor(c->c_mutex);
|
||||
+ /* Assert we really have the right job state. */
|
||||
+ PR_ASSERT(job == c->c_job);
|
||||
+
|
||||
+ /* On all code paths we remove the job, so set it null now */
|
||||
+ c->c_job = NULL;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "activity on conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
@@ -1829,6 +1877,7 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "queued conn %" PRIu64 " for fd=%d\n",
|
||||
c->c_connid, c->c_sd);
|
||||
}
|
||||
+ /* Since we call done on the job, we need to remove it here. */
|
||||
PR_ExitMonitor(c->c_mutex);
|
||||
ns_job_done(job);
|
||||
return;
|
||||
@@ -2451,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;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
|
||||
index 4d25a9fb8..f47bb6145 100644
|
||||
--- a/ldap/servers/slapd/fe.h
|
||||
+++ b/ldap/servers/slapd/fe.h
|
||||
@@ -100,6 +100,7 @@ extern Connection_Table *the_connection_table; /* JCM - Exported from globals.c
|
||||
Connection_Table *connection_table_new(int table_size);
|
||||
void connection_table_free(Connection_Table *ct);
|
||||
void connection_table_abandon_all_operations(Connection_Table *ct);
|
||||
+void connection_table_disconnect_all(Connection_Table *ct);
|
||||
Connection *connection_table_get_connection(Connection_Table *ct, int sd);
|
||||
int connection_table_move_connection_out_of_active_list(Connection_Table *ct, Connection *c);
|
||||
void connection_table_move_connection_on_to_active_list(Connection_Table *ct, Connection *c);
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 03355f5fe..de4ac35c0 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -1650,6 +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 */
|
||||
int c_ns_close_jobs; /* number of current close jobs */
|
||||
char *c_ipaddr; /* ip address str - used by monitor */
|
||||
} Connection;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -1,938 +0,0 @@
|
|||
From 19945c4807f6b3269fb65100ddaea5f596f68e72 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 18 May 2018 07:29:11 -0400
|
||||
Subject: [PATCH 1/6] Ticket 49576 - Update ds-replcheck for new conflict
|
||||
entries
|
||||
|
||||
Description: This patch addresses the recvent changes to conflict
|
||||
entries and tombstones.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49576
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 53e58cdbfb2a2672ac21cd9b6d59f8b345478324)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-replcheck | 456 +++++++++++++++++++---------
|
||||
1 file changed, 312 insertions(+), 144 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||||
index 45c4670a3..b801ccaa8 100755
|
||||
--- a/ldap/admin/src/scripts/ds-replcheck
|
||||
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# --- BEGIN COPYRIGHT BLOCK ---
|
||||
-# Copyright (C) 2017 Red Hat, Inc.
|
||||
+# Copyright (C) 2018 Red Hat, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# License: GPL (version 3 or any later version).
|
||||
@@ -9,6 +9,7 @@
|
||||
# --- END COPYRIGHT BLOCK ---
|
||||
#
|
||||
|
||||
+import os
|
||||
import re
|
||||
import time
|
||||
import ldap
|
||||
@@ -20,7 +21,7 @@ from ldap.ldapobject import SimpleLDAPObject
|
||||
from ldap.cidict import cidict
|
||||
from ldap.controls import SimplePagedResultsControl
|
||||
|
||||
-VERSION = "1.2"
|
||||
+VERSION = "1.3"
|
||||
RUV_FILTER = '(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))'
|
||||
LDAP = 'ldap'
|
||||
LDAPS = 'ldaps'
|
||||
@@ -36,6 +37,7 @@ class Entry(object):
|
||||
''' This is a stripped down version of Entry from python-lib389.
|
||||
Once python-lib389 is released on RHEL this class will go away.
|
||||
'''
|
||||
+
|
||||
def __init__(self, entrydata):
|
||||
if entrydata:
|
||||
self.dn = entrydata[0]
|
||||
@@ -51,7 +53,7 @@ class Entry(object):
|
||||
|
||||
|
||||
def get_entry(entries, dn):
|
||||
- ''' Loop over enties looking for a matching dn
|
||||
+ ''' Loop over a list of enties looking for a matching dn
|
||||
'''
|
||||
for entry in entries:
|
||||
if entry.dn == dn:
|
||||
@@ -60,7 +62,7 @@ def get_entry(entries, dn):
|
||||
|
||||
|
||||
def remove_entry(rentries, dn):
|
||||
- ''' Remove an entry from the array of entries
|
||||
+ ''' Remove an entry from the list of entries
|
||||
'''
|
||||
for entry in rentries:
|
||||
if entry.dn == dn:
|
||||
@@ -69,7 +71,7 @@ def remove_entry(rentries, dn):
|
||||
|
||||
|
||||
def extract_time(stateinfo):
|
||||
- ''' Take the nscpEntryWSI attribute and get the most recent timestamp from
|
||||
+ ''' Take the nscpEntryWSI(state info) attribute and get the most recent timestamp from
|
||||
one of the csns (vucsn, vdcsn, mdcsn, adcsn)
|
||||
|
||||
Return the timestamp in decimal
|
||||
@@ -87,7 +89,7 @@ def extract_time(stateinfo):
|
||||
|
||||
|
||||
def convert_timestamp(timestamp):
|
||||
- ''' Convert createtimestamp to ctime: 20170405184656Z -> Wed Apr 5 19:46:56 2017
|
||||
+ ''' Convert createtimestamp to ctime: 20170405184656Z ----> Wed Apr 5 19:46:56 2017
|
||||
'''
|
||||
time_tuple = (int(timestamp[:4]), int(timestamp[4:6]), int(timestamp[6:8]),
|
||||
int(timestamp[8:10]), int(timestamp[10:12]), int(timestamp[12:14]),
|
||||
@@ -97,27 +99,43 @@ def convert_timestamp(timestamp):
|
||||
|
||||
|
||||
def convert_entries(entries):
|
||||
- '''Convert and normalize the ldap entries. Take note of conflicts and tombstones
|
||||
- '''
|
||||
+ '''For online report. Convert and normalize the ldap entries. Take note of
|
||||
+ conflicts and tombstones '''
|
||||
new_entries = []
|
||||
conflict_entries = []
|
||||
+ glue_entries = []
|
||||
result = {}
|
||||
tombstones = 0
|
||||
+
|
||||
for entry in entries:
|
||||
new_entry = Entry(entry)
|
||||
new_entry.data = {k.lower(): v for k, v in list(new_entry.data.items())}
|
||||
- if 'nsds5replconflict' in new_entry.data:
|
||||
+ if new_entry.dn.endswith("cn=mapping tree,cn=config"):
|
||||
+ '''Skip replica entry (ldapsearch brings this in because the filter
|
||||
+ we use triggers an internal operation to return the config entry - so
|
||||
+ it must be skipped
|
||||
+ '''
|
||||
+ continue
|
||||
+ if ('nsds5replconflict' in new_entry.data and 'nsTombstone' not in new_entry.data['objectclass'] and
|
||||
+ 'nstombstone' not in new_entry.data['objectclass']):
|
||||
+ # This is a conflict entry that is NOT a tombstone entry (should this be reconsidered?)
|
||||
conflict_entries.append(new_entry)
|
||||
+ if 'glue' in new_entry.data['objectclass']:
|
||||
+ # A glue entry here is not necessarily a glue entry there. Keep track of
|
||||
+ # them for when we check missing entries
|
||||
+ glue_entries.append(new_entry)
|
||||
else:
|
||||
new_entries.append(new_entry)
|
||||
|
||||
if 'nstombstonecsn' in new_entry.data:
|
||||
+ # Maintain tombstone count
|
||||
tombstones += 1
|
||||
del entries
|
||||
|
||||
result['entries'] = new_entries
|
||||
result['conflicts'] = conflict_entries
|
||||
result['tombstones'] = tombstones
|
||||
+ result['glue'] = glue_entries
|
||||
|
||||
return result
|
||||
|
||||
@@ -174,20 +192,60 @@ def get_ruv_report(opts):
|
||||
return report
|
||||
|
||||
|
||||
+def remove_attr_state_info(attr):
|
||||
+ state_attr = None
|
||||
+ idx = attr.find(';')
|
||||
+ if idx > 0:
|
||||
+ state_attr = attr # preserve state info for diff report
|
||||
+ if ";deleted" in attr:
|
||||
+ # Ignore this attribute it was deleted
|
||||
+ return None, state_attr
|
||||
+ attr = attr[:idx]
|
||||
+
|
||||
+ return attr.lower(), state_attr
|
||||
+
|
||||
+def add_attr_entry(entry, val, attr, state_attr):
|
||||
+ ''' Offline mode (ldif comparision) Add the attr to the entry, and if there
|
||||
+ is state info add nscpentrywsi attr - we need consistency with online mode
|
||||
+ to make code simpler '''
|
||||
+ if attr is not None:
|
||||
+ if attr in entry:
|
||||
+ entry[attr].append(val)
|
||||
+ else:
|
||||
+ entry[attr] = [val]
|
||||
+
|
||||
+ # Handle state info for diff report
|
||||
+ if state_attr is not None:
|
||||
+ state_attr = state_attr + ": " + val
|
||||
+ if 'nscpentrywsi' in entry:
|
||||
+ entry['nscpentrywsi'].append(state_attr)
|
||||
+ else:
|
||||
+ entry['nscpentrywsi'] = [state_attr]
|
||||
+ val = ""
|
||||
+
|
||||
+
|
||||
#
|
||||
# Offline mode helper functions
|
||||
#
|
||||
-def ldif_search(LDIF, dn, conflicts=False):
|
||||
- ''' Search ldif by DN
|
||||
+def ldif_search(LDIF, dn):
|
||||
+ ''' Offline mode - Search ldif for a single DN. We need to factor in that
|
||||
+ DN's and attribute values can wrap lines and are identified by a leading
|
||||
+ white space. So we can't fully process an attribute until we get to the
|
||||
+ next attribute.
|
||||
'''
|
||||
result = {}
|
||||
data = {}
|
||||
found_conflict = False
|
||||
+ found_subentry = False
|
||||
found_part_dn = False
|
||||
+ found_part_val = False
|
||||
+ found_attr = False
|
||||
+ found_tombstone = False
|
||||
+ found_glue = False
|
||||
found = False
|
||||
- reset_line = False
|
||||
count = 0
|
||||
-
|
||||
+ ignore_list = ['conflictcsn', 'modifytimestamp', 'modifiersname']
|
||||
+ val = ""
|
||||
result['entry'] = None
|
||||
result['conflict'] = None
|
||||
result['tombstone'] = False
|
||||
@@ -195,54 +253,132 @@ def ldif_search(LDIF, dn, conflicts=False):
|
||||
for line in LDIF:
|
||||
count += 1
|
||||
line = line.rstrip()
|
||||
- if reset_line:
|
||||
- reset_line = False
|
||||
- line = prev_line
|
||||
+
|
||||
if found:
|
||||
+ # We found our entry, now build up the entry (account from line wrap)
|
||||
if line == "":
|
||||
- # End of entry
|
||||
+ # End of entry - update entry's last attribute value and break out
|
||||
+ add_attr_entry(data, val, attr, state_attr)
|
||||
+ val = ""
|
||||
+ # Done!
|
||||
break
|
||||
|
||||
if line[0] == ' ':
|
||||
- # continuation line
|
||||
- prev = data[attr][len(data[attr]) - 1]
|
||||
- data[attr][len(data[attr]) - 1] = prev + line.strip()
|
||||
+ # continuation line (wrapped value)
|
||||
+ val += line[1:]
|
||||
+ found_part_val = True
|
||||
continue
|
||||
+ elif found_part_val:
|
||||
+ # We have the complete value now (it was wrapped)
|
||||
+ found_part_val = False
|
||||
+ found_attr = False
|
||||
+ add_attr_entry(data, val, attr, state_attr)
|
||||
+
|
||||
+ # Now that the value is added to the entry lets process the new attribute...
|
||||
+ value_set = line.split(":", 1)
|
||||
+ attr, state_attr = remove_attr_state_info(value_set[0])
|
||||
+
|
||||
+ if attr in ignore_list or (attr is None and state_attr is None):
|
||||
+ # Skip it
|
||||
+ found_attr = False
|
||||
+ attr = None
|
||||
+ continue
|
||||
|
||||
- value_set = line.split(":", 1)
|
||||
- attr = value_set[0].lower()
|
||||
- if attr.startswith('nsds5replconflict'):
|
||||
- found_conflict = True
|
||||
- if attr.startswith('nstombstonecsn'):
|
||||
- result['tombstone'] = True
|
||||
-
|
||||
- if attr in data:
|
||||
- data[attr].append(value_set[1].strip())
|
||||
+ val = value_set[1].strip()
|
||||
+ found_attr = True
|
||||
+
|
||||
+ if attr is not None:
|
||||
+ # Set the entry type flags
|
||||
+ if attr.startswith('nsds5replconflict'):
|
||||
+ found_conflict = True
|
||||
+ if attr.startswith("objectclass") and val == "ldapsubentry":
|
||||
+ found_subentry = True
|
||||
+ if attr.startswith('nstombstonecsn'):
|
||||
+ result['tombstone'] = True
|
||||
+ found_tombstone = True
|
||||
+ continue
|
||||
else:
|
||||
- data[attr] = [value_set[1].strip()]
|
||||
+ # New attribute...
|
||||
+ if found_attr:
|
||||
+ # But first we have to add the previous complete attr value to the entry data
|
||||
+ add_attr_entry(data, val, attr, state_attr)
|
||||
+
|
||||
+ # Process new attribute
|
||||
+ value_set = line.split(":", 1)
|
||||
+ attr, state_attr = remove_attr_state_info(value_set[0])
|
||||
+ if attr is None or attr in ignore_list:
|
||||
+ # Skip it (its deleted)
|
||||
+ found_attr = False
|
||||
+ attr = None
|
||||
+ continue
|
||||
+
|
||||
+ val = value_set[1].strip()
|
||||
+ found_attr = True
|
||||
+
|
||||
+ # Set the entry type flags
|
||||
+ if attr.startswith('nsds5replconflict'):
|
||||
+ found_conflict = True
|
||||
+ if attr.startswith("objectclass") and (val == "ldapsubentry" or val == "glue"):
|
||||
+ if val == "glue":
|
||||
+ found_glue = True
|
||||
+ found_subentry = True
|
||||
+ if attr.startswith('nstombstonecsn'):
|
||||
+ result['tombstone'] = True
|
||||
+ found_tombstone = True
|
||||
+ continue
|
||||
+
|
||||
elif found_part_dn:
|
||||
if line[0] == ' ':
|
||||
+ # DN is still wrapping, keep building up the dn value
|
||||
part_dn += line[1:].lower()
|
||||
else:
|
||||
- # We have the full dn
|
||||
+ # We now have the full dn
|
||||
found_part_dn = False
|
||||
- reset_line = True
|
||||
- prev_line = line
|
||||
if part_dn == dn:
|
||||
+ # We found our entry
|
||||
found = True
|
||||
+
|
||||
+ # But now we have a new attribute to process
|
||||
+ value_set = line.split(":", 1)
|
||||
+ attr, state_attr = remove_attr_state_info(value_set[0])
|
||||
+ if attr is None or attr in ignore_list:
|
||||
+ # Skip it (its deleted)
|
||||
+ found_attr = False
|
||||
+ attr = None
|
||||
+ continue
|
||||
+
|
||||
+ val = value_set[1].strip()
|
||||
+ found_attr = True
|
||||
+
|
||||
+ if attr.startswith('nsds5replconflict'):
|
||||
+ found_conflict = True
|
||||
+ if attr.startswith("objectclass") and val == "ldapsubentry":
|
||||
+ found_subentry = True
|
||||
+
|
||||
+ if attr.startswith('nstombstonecsn'):
|
||||
+ result['tombstone'] = True
|
||||
+ found_tombstone = True
|
||||
continue
|
||||
+
|
||||
if line.startswith('dn: '):
|
||||
if line[4:].lower() == dn:
|
||||
+ # We got our full DN, now process the entry
|
||||
found = True
|
||||
continue
|
||||
else:
|
||||
+ # DN wraps the line, keep looping until we get the whole value
|
||||
part_dn = line[4:].lower()
|
||||
found_part_dn = True
|
||||
|
||||
+ # Keep track of entry index - we use this later when searching the LDIF again
|
||||
result['idx'] = count
|
||||
- if found_conflict:
|
||||
+
|
||||
+ result['glue'] = None
|
||||
+ if found_conflict and found_subentry and found_tombstone is False:
|
||||
result['entry'] = None
|
||||
result['conflict'] = Entry([dn, data])
|
||||
+ if found_glue:
|
||||
+ result['glue'] = result['conflict']
|
||||
elif found:
|
||||
result['conflict'] = None
|
||||
result['entry'] = Entry([dn, data])
|
||||
@@ -251,7 +387,7 @@ def ldif_search(LDIF, dn, conflicts=False):
|
||||
|
||||
|
||||
def get_dns(LDIF, opts):
|
||||
- ''' Get all the DN's
|
||||
+ ''' Get all the DN's from an LDIF file
|
||||
'''
|
||||
dns = []
|
||||
found = False
|
||||
@@ -275,7 +411,7 @@ def get_dns(LDIF, opts):
|
||||
|
||||
|
||||
def get_ldif_ruv(LDIF, opts):
|
||||
- ''' Search the ldif and get the ruv entry
|
||||
+ ''' Search the LDIF and get the ruv entry
|
||||
'''
|
||||
LDIF.seek(0)
|
||||
result = ldif_search(LDIF, opts['ruv_dn'])
|
||||
@@ -283,7 +419,7 @@ def get_ldif_ruv(LDIF, opts):
|
||||
|
||||
|
||||
def cmp_entry(mentry, rentry, opts):
|
||||
- ''' Compare the two entries, and return a diff map
|
||||
+ ''' Compare the two entries, and return a "diff map"
|
||||
'''
|
||||
diff = {}
|
||||
diff['dn'] = mentry['dn']
|
||||
@@ -307,6 +443,7 @@ def cmp_entry(mentry, rentry, opts):
|
||||
diff['missing'].append(" - Replica missing attribute: \"%s\"" % (mattr))
|
||||
diff_count += 1
|
||||
if 'nscpentrywsi' in mentry.data:
|
||||
+ # Great we have state info so we can provide details about the missing attribute
|
||||
found = False
|
||||
for val in mentry.data['nscpentrywsi']:
|
||||
if val.lower().startswith(mattr + ';'):
|
||||
@@ -316,6 +453,7 @@ def cmp_entry(mentry, rentry, opts):
|
||||
diff['missing'].append(" - Master's State Info: %s" % (val))
|
||||
diff['missing'].append(" - Date: %s\n" % (time.ctime(extract_time(val))))
|
||||
else:
|
||||
+ # No state info, just move on
|
||||
diff['missing'].append("")
|
||||
|
||||
elif mentry.data[mattr] != rentry.data[mattr]:
|
||||
@@ -335,6 +473,9 @@ def cmp_entry(mentry, rentry, opts):
|
||||
if not found:
|
||||
diff['diff'].append(" Master: ")
|
||||
for val in mentry.data[mattr]:
|
||||
+ # This is an "origin" value which means it's never been
|
||||
+ # updated since replication was set up. So its the
|
||||
+ # original value
|
||||
diff['diff'].append(" - Origin value: %s" % (val))
|
||||
diff['diff'].append("")
|
||||
|
||||
@@ -350,10 +491,13 @@ def cmp_entry(mentry, rentry, opts):
|
||||
if not found:
|
||||
diff['diff'].append(" Replica: ")
|
||||
for val in rentry.data[mattr]:
|
||||
+ # This is an "origin" value which means it's never been
|
||||
+ # updated since replication was set up. So its the
|
||||
+ # original value
|
||||
diff['diff'].append(" - Origin value: %s" % (val))
|
||||
diff['diff'].append("")
|
||||
else:
|
||||
- # no state info
|
||||
+ # no state info, report what we got
|
||||
diff['diff'].append(" Master: ")
|
||||
for val in mentry.data[mattr]:
|
||||
diff['diff'].append(" - %s: %s" % (mattr, val))
|
||||
@@ -436,40 +580,62 @@ def do_offline_report(opts, output_file=None):
|
||||
MLDIF.seek(idx)
|
||||
RLDIF.seek(idx)
|
||||
|
||||
- # Compare the master entries with the replica's
|
||||
+ """ Compare the master entries with the replica's. Take our list of dn's from
|
||||
+ the master ldif and get that entry( dn) from the master and replica ldif. In
|
||||
+ this phase we keep keep track of conflict/tombstone counts, and we check for
|
||||
+ missing entries and entry differences. We only need to do the entry diff
|
||||
+ checking in this phase - we do not need to do it when process the replica dn's
|
||||
+ because if the entry exists in both LDIF's then we already checked or diffs
|
||||
+ while processing the master dn's.
|
||||
+ """
|
||||
print ("Comparing Master to Replica...")
|
||||
missing = False
|
||||
for dn in master_dns:
|
||||
- mresult = ldif_search(MLDIF, dn, True)
|
||||
- rresult = ldif_search(RLDIF, dn, True)
|
||||
+ mresult = ldif_search(MLDIF, dn)
|
||||
+ rresult = ldif_search(RLDIF, dn)
|
||||
+
|
||||
+ if dn in replica_dns:
|
||||
+ if (rresult['entry'] is not None or rresult['glue'] is not None or
|
||||
+ rresult['conflict'] is not None or rresult['tombstone']):
|
||||
+ """ We can safely remove this DN from the replica dn list as it
|
||||
+ does not need to be checked again. This also speeds things up
|
||||
+ when doing the replica vs master phase.
|
||||
+ """
|
||||
+ replica_dns.remove(dn)
|
||||
|
||||
if mresult['tombstone']:
|
||||
mtombstones += 1
|
||||
+ # continue
|
||||
+ if rresult['tombstone']:
|
||||
+ rtombstones += 1
|
||||
|
||||
if mresult['conflict'] is not None or rresult['conflict'] is not None:
|
||||
+ # If either entry is a conflict we still process it here
|
||||
if mresult['conflict'] is not None:
|
||||
mconflicts.append(mresult['conflict'])
|
||||
+ if rresult['conflict'] is not None:
|
||||
+ rconflicts.append(rresult['conflict'])
|
||||
elif rresult['entry'] is None:
|
||||
- # missing entry - restart the search from beginning
|
||||
+ # missing entry - restart the search from beginning in case it got skipped
|
||||
RLDIF.seek(0)
|
||||
rresult = ldif_search(RLDIF, dn)
|
||||
- if rresult['entry'] is None:
|
||||
- # missing entry in rentries
|
||||
- RLDIF.seek(mresult['idx']) # Set the cursor to the last good line
|
||||
+ if rresult['entry'] is None and rresult['glue'] is None:
|
||||
+ # missing entry in Replica(rentries)
|
||||
+ RLDIF.seek(mresult['idx']) # Set the LDIF cursor/index to the last good line
|
||||
if not missing:
|
||||
- missing_report += ('Replica is missing entries:\n')
|
||||
+ missing_report += (' Entries missing on Replica:\n')
|
||||
missing = True
|
||||
if mresult['entry'] and 'createtimestamp' in mresult['entry'].data:
|
||||
- missing_report += (' - %s (Master\'s creation date: %s)\n' %
|
||||
+ missing_report += (' - %s (Created on Master at: %s)\n' %
|
||||
(dn, convert_timestamp(mresult['entry'].data['createtimestamp'][0])))
|
||||
else:
|
||||
missing_report += (' - %s\n' % dn)
|
||||
- else:
|
||||
+ elif mresult['tombstone'] is False:
|
||||
# Compare the entries
|
||||
diff = cmp_entry(mresult['entry'], rresult['entry'], opts)
|
||||
if diff:
|
||||
diff_report.append(format_diff(diff))
|
||||
- else:
|
||||
+ elif mresult['tombstone'] is False:
|
||||
# Compare the entries
|
||||
diff = cmp_entry(mresult['entry'], rresult['entry'], opts)
|
||||
if diff:
|
||||
@@ -478,7 +644,10 @@ def do_offline_report(opts, output_file=None):
|
||||
if missing:
|
||||
missing_report += ('\n')
|
||||
|
||||
- # Search Replica, and look for missing entries only. Count entries as well
|
||||
+ """ Search Replica, and look for missing entries only. We already did the
|
||||
+ diff checking, so its only missing entries we are worried about. Count the
|
||||
+ remaining conflict & tombstone entries as well.
|
||||
+ """
|
||||
print ("Comparing Replica to Master...")
|
||||
MLDIF.seek(0)
|
||||
RLDIF.seek(0)
|
||||
@@ -486,26 +655,26 @@ def do_offline_report(opts, output_file=None):
|
||||
for dn in replica_dns:
|
||||
rresult = ldif_search(RLDIF, dn)
|
||||
mresult = ldif_search(MLDIF, dn)
|
||||
-
|
||||
if rresult['tombstone']:
|
||||
rtombstones += 1
|
||||
- if mresult['entry'] is not None or rresult['conflict'] is not None:
|
||||
- if rresult['conflict'] is not None:
|
||||
- rconflicts.append(rresult['conflict'])
|
||||
+ # continue
|
||||
+
|
||||
+ if rresult['conflict'] is not None:
|
||||
+ rconflicts.append(rresult['conflict'])
|
||||
elif mresult['entry'] is None:
|
||||
# missing entry
|
||||
MLDIF.seek(0)
|
||||
mresult = ldif_search(MLDIF, dn)
|
||||
- if mresult['entry'] is None and mresult['conflict'] is not None:
|
||||
- MLDIF.seek(rresult['idx']) # Set the cursor to the last good line
|
||||
+ if mresult['entry'] is None and mresult['glue'] is None:
|
||||
+ MLDIF.seek(rresult['idx']) # Set the LDIF cursor/index to the last good line
|
||||
if not missing:
|
||||
- missing_report += ('Master is missing entries:\n')
|
||||
+ missing_report += (' Entries missing on Master:\n')
|
||||
missing = True
|
||||
- if 'createtimestamp' in rresult['entry'].data:
|
||||
- missing_report += (' - %s (Replica\'s creation date: %s)\n' %
|
||||
+ if rresult['entry'] and 'createtimestamp' in rresult['entry'].data:
|
||||
+ missing_report += (' - %s (Created on Replica at: %s)\n' %
|
||||
(dn, convert_timestamp(rresult['entry'].data['createtimestamp'][0])))
|
||||
else:
|
||||
- missing_report += (' - %s\n')
|
||||
+ missing_report += (' - %s\n' % dn)
|
||||
if missing:
|
||||
missing_report += ('\n')
|
||||
|
||||
@@ -553,8 +722,8 @@ def do_offline_report(opts, output_file=None):
|
||||
print(final_report)
|
||||
|
||||
|
||||
-def check_for_diffs(mentries, rentries, report, opts):
|
||||
- ''' Check for diffs, return the updated report
|
||||
+def check_for_diffs(mentries, mglue, rentries, rglue, report, opts):
|
||||
+ ''' Online mode only - Check for diffs, return the updated report
|
||||
'''
|
||||
diff_report = []
|
||||
m_missing = []
|
||||
@@ -569,18 +738,26 @@ def check_for_diffs(mentries, rentries, report, opts):
|
||||
for mentry in mentries:
|
||||
rentry = get_entry(rentries, mentry.dn)
|
||||
if rentry:
|
||||
- diff = cmp_entry(mentry, rentry, opts)
|
||||
- if diff:
|
||||
- diff_report.append(format_diff(diff))
|
||||
+ if 'nsTombstone' not in rentry.data['objectclass'] and 'nstombstone' not in rentry.data['objectclass']:
|
||||
+ diff = cmp_entry(mentry, rentry, opts)
|
||||
+ if diff:
|
||||
+ diff_report.append(format_diff(diff))
|
||||
# Now remove the rentry from the rentries so we can find stragglers
|
||||
remove_entry(rentries, rentry.dn)
|
||||
else:
|
||||
- # Add missing entry in Replica
|
||||
- r_missing.append(mentry)
|
||||
+ rentry = get_entry(rglue, mentry.dn)
|
||||
+ if rentry:
|
||||
+ # Glue entry nothing to compare
|
||||
+ remove_entry(rentries, rentry.dn)
|
||||
+ else:
|
||||
+ # Add missing entry in Replica
|
||||
+ r_missing.append(mentry)
|
||||
|
||||
for rentry in rentries:
|
||||
# We should not have any entries if we are sync
|
||||
- m_missing.append(rentry)
|
||||
+ mentry = get_entry(mglue, rentry.dn)
|
||||
+ if mentry is None:
|
||||
+ m_missing.append(rentry)
|
||||
|
||||
if len(diff_report) > 0:
|
||||
report['diff'] += diff_report
|
||||
@@ -609,6 +786,12 @@ def connect_to_replicas(opts):
|
||||
ruri = "%s://%s:%s/" % (opts['rprotocol'], opts['rhost'], opts['rport'])
|
||||
replica = SimpleLDAPObject(ruri)
|
||||
|
||||
+ # Set timeouts
|
||||
+ master.set_option(ldap.OPT_NETWORK_TIMEOUT,5.0)
|
||||
+ master.set_option(ldap.OPT_TIMEOUT,5.0)
|
||||
+ replica.set_option(ldap.OPT_NETWORK_TIMEOUT,5.0)
|
||||
+ replica.set_option(ldap.OPT_TIMEOUT,5.0)
|
||||
+
|
||||
# Setup Secure Conenction
|
||||
if opts['certdir'] is not None:
|
||||
# Setup Master
|
||||
@@ -620,7 +803,7 @@ def connect_to_replicas(opts):
|
||||
try:
|
||||
master.start_tls_s()
|
||||
except ldap.LDAPError as e:
|
||||
- print('TLS negotiation failed on Master: %s' % str(e))
|
||||
+ print('TLS negotiation failed on Master: {}'.format(str(e)))
|
||||
exit(1)
|
||||
|
||||
# Setup Replica
|
||||
@@ -632,7 +815,7 @@ def connect_to_replicas(opts):
|
||||
try:
|
||||
replica.start_tls_s()
|
||||
except ldap.LDAPError as e:
|
||||
- print('TLS negotiation failed on Master: %s' % str(e))
|
||||
+ print('TLS negotiation failed on Master: {}'.format(str(e)))
|
||||
exit(1)
|
||||
|
||||
# Open connection to master
|
||||
@@ -642,7 +825,8 @@ def connect_to_replicas(opts):
|
||||
print("Cannot connect to %r" % muri)
|
||||
exit(1)
|
||||
except ldap.LDAPError as e:
|
||||
- print("Error: Failed to authenticate to Master: %s", str(e))
|
||||
+ print("Error: Failed to authenticate to Master: ({}). "
|
||||
+ "Please check your credentials and LDAP urls are correct.".format(str(e)))
|
||||
exit(1)
|
||||
|
||||
# Open connection to replica
|
||||
@@ -652,7 +836,8 @@ def connect_to_replicas(opts):
|
||||
print("Cannot connect to %r" % ruri)
|
||||
exit(1)
|
||||
except ldap.LDAPError as e:
|
||||
- print("Error: Failed to authenticate to Replica: %s", str(e))
|
||||
+ print("Error: Failed to authenticate to Replica: ({}). "
|
||||
+ "Please check your credentials and LDAP urls are correct.".format(str(e)))
|
||||
exit(1)
|
||||
|
||||
# Get the RUVs
|
||||
@@ -665,7 +850,7 @@ def connect_to_replicas(opts):
|
||||
print("Error: Master does not have an RUV entry")
|
||||
exit(1)
|
||||
except ldap.LDAPError as e:
|
||||
- print("Error: Failed to get Master RUV entry: %s", str(e))
|
||||
+ print("Error: Failed to get Master RUV entry: {}".format(str(e)))
|
||||
exit(1)
|
||||
|
||||
print ("Gathering Replica's RUV...")
|
||||
@@ -678,7 +863,7 @@ def connect_to_replicas(opts):
|
||||
exit(1)
|
||||
|
||||
except ldap.LDAPError as e:
|
||||
- print("Error: Failed to get Replica RUV entry: %s", str(e))
|
||||
+ print("Error: Failed to get Replica RUV entry: {}".format(str(e)))
|
||||
exit(1)
|
||||
|
||||
return (master, replica, opts)
|
||||
@@ -687,6 +872,7 @@ def connect_to_replicas(opts):
|
||||
def print_online_report(report, opts, output_file):
|
||||
''' Print the online report
|
||||
'''
|
||||
+
|
||||
print ('Preparing final report...')
|
||||
m_missing = len(report['m_missing'])
|
||||
r_missing = len(report['r_missing'])
|
||||
@@ -711,22 +897,23 @@ def print_online_report(report, opts, output_file):
|
||||
missing = True
|
||||
final_report += ('\nMissing Entries\n')
|
||||
final_report += ('=====================================================\n\n')
|
||||
- if m_missing > 0:
|
||||
- final_report += (' Entries missing on Master:\n')
|
||||
- for entry in report['m_missing']:
|
||||
+
|
||||
+ if r_missing > 0:
|
||||
+ final_report += (' Entries missing on Replica:\n')
|
||||
+ for entry in report['r_missing']:
|
||||
if 'createtimestamp' in entry.data:
|
||||
- final_report += (' - %s (Created on Replica at: %s)\n' %
|
||||
+ final_report += (' - %s (Created on Master at: %s)\n' %
|
||||
(entry.dn, convert_timestamp(entry.data['createtimestamp'][0])))
|
||||
else:
|
||||
final_report += (' - %s\n' % (entry.dn))
|
||||
|
||||
- if r_missing > 0:
|
||||
- if m_missing > 0:
|
||||
+ if m_missing > 0:
|
||||
+ if r_missing > 0:
|
||||
final_report += ('\n')
|
||||
- final_report += (' Entries missing on Replica:\n')
|
||||
- for entry in report['r_missing']:
|
||||
+ final_report += (' Entries missing on Master:\n')
|
||||
+ for entry in report['m_missing']:
|
||||
if 'createtimestamp' in entry.data:
|
||||
- final_report += (' - %s (Created on Master at: %s)\n' %
|
||||
+ final_report += (' - %s (Created on Replica at: %s)\n' %
|
||||
(entry.dn, convert_timestamp(entry.data['createtimestamp'][0])))
|
||||
else:
|
||||
final_report += (' - %s\n' % (entry.dn))
|
||||
@@ -751,7 +938,8 @@ def print_online_report(report, opts, output_file):
|
||||
def remove_state_info(entry):
|
||||
''' Remove the state info for the attributes used in the conflict report
|
||||
'''
|
||||
- attrs = ['objectclass', 'nsds5replconflict', 'createtimestamp']
|
||||
+ attrs = ['objectclass', 'nsds5replconflict', 'createtimestamp' , 'modifytimestamp']
|
||||
+ # attrs = ['createtimestamp']
|
||||
for key, val in list(entry.data.items()):
|
||||
for attr in attrs:
|
||||
if key.lower().startswith(attr):
|
||||
@@ -766,9 +954,6 @@ def get_conflict_report(mentries, rentries, verbose, format_conflicts=False):
|
||||
r_conflicts = []
|
||||
|
||||
for entry in mentries:
|
||||
- if format_conflicts:
|
||||
- remove_state_info(entry)
|
||||
-
|
||||
if 'glue' in entry.data['objectclass']:
|
||||
m_conflicts.append({'dn': entry.dn, 'conflict': entry.data['nsds5replconflict'][0],
|
||||
'date': entry.data['createtimestamp'][0], 'glue': 'yes'})
|
||||
@@ -776,9 +961,6 @@ def get_conflict_report(mentries, rentries, verbose, format_conflicts=False):
|
||||
m_conflicts.append({'dn': entry.dn, 'conflict': entry.data['nsds5replconflict'][0],
|
||||
'date': entry.data['createtimestamp'][0], 'glue': 'no'})
|
||||
for entry in rentries:
|
||||
- if format_conflicts:
|
||||
- remove_state_info(entry)
|
||||
-
|
||||
if 'glue' in entry.data['objectclass']:
|
||||
r_conflicts.append({'dn': entry.dn, 'conflict': entry.data['nsds5replconflict'][0],
|
||||
'date': entry.data['createtimestamp'][0], 'glue': 'yes'})
|
||||
@@ -790,7 +972,7 @@ def get_conflict_report(mentries, rentries, verbose, format_conflicts=False):
|
||||
report = "\n\nConflict Entries\n"
|
||||
report += "=====================================================\n\n"
|
||||
if len(m_conflicts) > 0:
|
||||
- report += ('Master Conflict Entries: %d\n' % (len(m_conflicts)))
|
||||
+ report += ('Master Conflict Entries: %d\n' % (len(m_conflicts)))
|
||||
if verbose:
|
||||
for entry in m_conflicts:
|
||||
report += ('\n - %s\n' % (entry['dn']))
|
||||
@@ -799,7 +981,7 @@ def get_conflict_report(mentries, rentries, verbose, format_conflicts=False):
|
||||
report += (' - Created: %s\n' % (convert_timestamp(entry['date'])))
|
||||
|
||||
if len(r_conflicts) > 0:
|
||||
- if len(m_conflicts) > 0:
|
||||
+ if len(m_conflicts) > 0 and verbose:
|
||||
report += "\n" # add spacer
|
||||
report += ('Replica Conflict Entries: %d\n' % (len(r_conflicts)))
|
||||
if verbose:
|
||||
@@ -814,46 +996,6 @@ def get_conflict_report(mentries, rentries, verbose, format_conflicts=False):
|
||||
return ""
|
||||
|
||||
|
||||
-def get_tombstones(replica, opts):
|
||||
- ''' Return the number of tombstones
|
||||
- '''
|
||||
- paged_ctrl = SimplePagedResultsControl(True, size=opts['pagesize'], cookie='')
|
||||
- controls = [paged_ctrl]
|
||||
- req_pr_ctrl = controls[0]
|
||||
- count = 0
|
||||
-
|
||||
- try:
|
||||
- msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
- '(&(objectclass=nstombstone)(nstombstonecsn=*))',
|
||||
- ['dn'], serverctrls=controls)
|
||||
- except ldap.LDAPError as e:
|
||||
- print("Error: Failed to get tombstone entries: %s", str(e))
|
||||
- exit(1)
|
||||
-
|
||||
- done = False
|
||||
- while not done:
|
||||
- rtype, rdata, rmsgid, rctrls = replica.result3(msgid)
|
||||
- count += len(rdata)
|
||||
-
|
||||
- pctrls = [
|
||||
- c
|
||||
- for c in rctrls
|
||||
- if c.controlType == SimplePagedResultsControl.controlType
|
||||
- ]
|
||||
- if pctrls:
|
||||
- if pctrls[0].cookie:
|
||||
- # Copy cookie from response control to request control
|
||||
- req_pr_ctrl.cookie = pctrls[0].cookie
|
||||
- msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
- '(&(objectclass=nstombstone)(nstombstonecsn=*))',
|
||||
- ['dn'], serverctrls=controls)
|
||||
- else:
|
||||
- done = True # No more pages available
|
||||
- else:
|
||||
- done = True
|
||||
- return count
|
||||
-
|
||||
-
|
||||
def do_online_report(opts, output_file=None):
|
||||
''' Check for differences between two replicas
|
||||
'''
|
||||
@@ -880,7 +1022,7 @@ def do_online_report(opts, output_file=None):
|
||||
req_pr_ctrl = controls[0]
|
||||
try:
|
||||
master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
- "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry)(objectclass=nstombstone))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'],
|
||||
serverctrls=controls)
|
||||
except ldap.LDAPError as e:
|
||||
@@ -888,7 +1030,7 @@ def do_online_report(opts, output_file=None):
|
||||
exit(1)
|
||||
try:
|
||||
replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
- "(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
+ "(|(objectclass=*)(objectclass=ldapsubentry)(objectclass=nstombstone))",
|
||||
['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'],
|
||||
serverctrls=controls)
|
||||
except ldap.LDAPError as e:
|
||||
@@ -918,7 +1060,9 @@ def do_online_report(opts, output_file=None):
|
||||
rconflicts += rresult['conflicts']
|
||||
|
||||
# Check for diffs
|
||||
- report = check_for_diffs(mresult['entries'], rresult['entries'], report, opts)
|
||||
+ report = check_for_diffs(mresult['entries'], mresult['glue'],
|
||||
+ rresult['entries'], rresult['glue'],
|
||||
+ report, opts)
|
||||
|
||||
if not m_done:
|
||||
# Master
|
||||
@@ -933,7 +1077,7 @@ def do_online_report(opts, output_file=None):
|
||||
req_pr_ctrl.cookie = m_pctrls[0].cookie
|
||||
master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
"(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
- ['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'], serverctrls=controls)
|
||||
+ ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
|
||||
else:
|
||||
m_done = True # No more pages available
|
||||
else:
|
||||
@@ -953,7 +1097,7 @@ def do_online_report(opts, output_file=None):
|
||||
req_pr_ctrl.cookie = r_pctrls[0].cookie
|
||||
replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
|
||||
"(|(objectclass=*)(objectclass=ldapsubentry))",
|
||||
- ['*', 'createtimestamp', 'nscpentrywsi', 'nsds5replconflict'], serverctrls=controls)
|
||||
+ ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
|
||||
else:
|
||||
r_done = True # No more pages available
|
||||
else:
|
||||
@@ -961,10 +1105,8 @@ def do_online_report(opts, output_file=None):
|
||||
|
||||
# Get conflicts & tombstones
|
||||
report['conflict'] = get_conflict_report(mconflicts, rconflicts, opts['conflicts'])
|
||||
- report['mtombstones'] = get_tombstones(master, opts)
|
||||
- report['rtombstones'] = get_tombstones(replica, opts)
|
||||
- report['m_count'] += report['mtombstones']
|
||||
- report['r_count'] += report['rtombstones']
|
||||
+ report['mtombstones'] = mresult['tombstones']
|
||||
+ report['rtombstones'] = rresult['tombstones']
|
||||
|
||||
# Do the final report
|
||||
print_online_report(report, opts, output_file)
|
||||
@@ -1027,11 +1169,16 @@ def main():
|
||||
|
||||
# Parse the ldap URLs
|
||||
if args.murl is not None and args.rurl is not None:
|
||||
+ # Make sure the URLs are different
|
||||
+ if args.murl == args.rurl:
|
||||
+ print("Master and Replica LDAP URLs are the same, they must be different")
|
||||
+ exit(1)
|
||||
+
|
||||
# Parse Master url
|
||||
- murl = ldapurl.LDAPUrl(args.murl)
|
||||
if not ldapurl.isLDAPUrl(args.murl):
|
||||
print("Master LDAP URL is invalid")
|
||||
exit(1)
|
||||
+ murl = ldapurl.LDAPUrl(args.murl)
|
||||
if murl.urlscheme in VALID_PROTOCOLS:
|
||||
opts['mprotocol'] = murl.urlscheme
|
||||
else:
|
||||
@@ -1052,10 +1199,10 @@ def main():
|
||||
opts['mport'] = parts[1]
|
||||
|
||||
# Parse Replica url
|
||||
- rurl = ldapurl.LDAPUrl(args.rurl)
|
||||
if not ldapurl.isLDAPUrl(args.rurl):
|
||||
print("Replica LDAP URL is invalid")
|
||||
exit(1)
|
||||
+ rurl = ldapurl.LDAPUrl(args.rurl)
|
||||
if rurl.urlscheme in VALID_PROTOCOLS:
|
||||
opts['rprotocol'] = rurl.urlscheme
|
||||
else:
|
||||
@@ -1075,11 +1222,19 @@ def main():
|
||||
opts['rhost'] = parts[0]
|
||||
opts['rport'] = parts[1]
|
||||
|
||||
+ # Validate certdir
|
||||
+ opts['certdir'] = None
|
||||
+ if args.certdir:
|
||||
+ if os.path.exists() and os.path.isdir(certdir):
|
||||
+ opts['certdir'] = args.certdir
|
||||
+ else:
|
||||
+ print("certificate directory ({}) does not exist or is not a directory".format(args.certdir))
|
||||
+ exit(1)
|
||||
+
|
||||
# Initialize the options
|
||||
opts['binddn'] = args.binddn
|
||||
opts['bindpw'] = args.bindpw
|
||||
opts['suffix'] = args.suffix
|
||||
- opts['certdir'] = args.certdir
|
||||
opts['starttime'] = int(time.time())
|
||||
opts['verbose'] = args.verbose
|
||||
opts['mldif'] = args.mldif
|
||||
@@ -1109,6 +1264,18 @@ def main():
|
||||
|
||||
if opts['mldif'] is not None and opts['rldif'] is not None:
|
||||
print ("Performing offline report...")
|
||||
+
|
||||
+ # Validate LDIF files, must exist and not be empty
|
||||
+ for ldif_dir in [opts['mldif'], opts['rldif']]:
|
||||
+ if not os.path.exists(ldif_dir):
|
||||
+ print ("LDIF file ({}) does not exist".format(ldif_dir))
|
||||
+ exit(1)
|
||||
+ if os.path.getsize(ldif_dir) == 0:
|
||||
+ print ("LDIF file ({}) is empty".format(ldif_dir))
|
||||
+ exit(1)
|
||||
+ if opts['mldif'] == opts['rldif']:
|
||||
+ print("The Master and Replica LDIF files must be different")
|
||||
+ exit(1)
|
||||
do_offline_report(opts, OUTPUT_FILE)
|
||||
else:
|
||||
print ("Performing online report...")
|
||||
@@ -1118,5 +1285,6 @@ def main():
|
||||
print('Finished writing report to "%s"' % (args.file))
|
||||
OUTPUT_FILE.close()
|
||||
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
From 00ebe4e4298fb19d9b8fc78b16053fb0b92eea9f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 25 May 2018 09:47:31 -0400
|
||||
Subject: [PATCH] Ticket 49576 - Add support of ";deletedattribute" in
|
||||
ds-replcheck
|
||||
|
||||
Description: Also need to check for ";deletedattribute" when processing LDIF file
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49576
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 9e046a35a0f771e77c788cddee2cbddee6ae0571)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-replcheck | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||||
index b801ccaa8..661c9e0ce 100755
|
||||
--- a/ldap/admin/src/scripts/ds-replcheck
|
||||
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||||
@@ -197,7 +197,7 @@ def remove_attr_state_info(attr):
|
||||
idx = attr.find(';')
|
||||
if idx > 0:
|
||||
state_attr = attr # preserve state info for diff report
|
||||
- if ";deleted" in attr:
|
||||
+ if ";deleted" in attr or ";deletedattribute" in attr:
|
||||
# Ignore this attribute it was deleted
|
||||
return None, state_attr
|
||||
attr = attr[:idx]
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -1,529 +0,0 @@
|
|||
From b6894f921a0635dba97a0745ce75917284e5e5ff Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Sun, 27 May 2018 10:48:55 -0400
|
||||
Subject: [PATCH] Ticket 49726 - DS only accepts RSA and Fortezza cipher
|
||||
families
|
||||
|
||||
Bug Description: Currently DS only accepts fortezza and RSA cipher families.
|
||||
This prevents things like ECC certificates from being used.
|
||||
|
||||
Fix Description: Instead of hardcoding the cipher families, just grab the
|
||||
current type and use it.
|
||||
|
||||
Also cleaned up code: removed unncessary "ifdefs", and switched
|
||||
for loops to use size_t.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49726
|
||||
|
||||
Reviewed by: ?
|
||||
|
||||
(cherry picked from commit 27a16a068887e5b9fcab3b4507d58a18e6f1d1ec)
|
||||
---
|
||||
ldap/servers/slapd/ssl.c | 136 ++++++---------------------------------
|
||||
1 file changed, 20 insertions(+), 116 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
|
||||
index 36b09fd16..b8eba2da4 100644
|
||||
--- a/ldap/servers/slapd/ssl.c
|
||||
+++ b/ldap/servers/slapd/ssl.c
|
||||
@@ -31,28 +31,11 @@
|
||||
#include "fe.h"
|
||||
#include "certdb.h"
|
||||
|
||||
-#if !defined(USE_OPENLDAP)
|
||||
-#include "ldap_ssl.h"
|
||||
-#endif
|
||||
-
|
||||
/* For IRIX... */
|
||||
#ifndef MAXPATHLEN
|
||||
#define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
-#if NSS_VMAJOR * 100 + NSS_VMINOR >= 315
|
||||
-/* TLS1.2 is defined in RFC5246. */
|
||||
-#define NSS_TLS12 1
|
||||
-#elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314
|
||||
-/* TLS1.1 is defined in RFC4346. */
|
||||
-#define NSS_TLS11 1
|
||||
-#else
|
||||
-#define NSS_TLS10 1
|
||||
-#endif
|
||||
-
|
||||
-#if NSS_VMAJOR * 100 + NSS_VMINOR >= 320
|
||||
-#define HAVE_NSS_DHE 1
|
||||
-#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Default SSL Version Rule
|
||||
@@ -70,10 +53,9 @@
|
||||
|
||||
extern char *slapd_SSL3ciphers;
|
||||
extern symbol_t supported_ciphers[];
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
static SSLVersionRange enabledNSSVersions;
|
||||
static SSLVersionRange slapdNSSVersions;
|
||||
-#endif
|
||||
+
|
||||
|
||||
/* dongle_file_name is set in slapd_nss_init when we set the path for the
|
||||
key, cert, and secmod files - the dongle file must be in the same directory
|
||||
@@ -109,12 +91,10 @@ static char *configDN = "cn=encryption,cn=config";
|
||||
#define CIPHER_SET_DEFAULTWEAKCIPHER 0x10 /* allowWeakCipher is not set in cn=encryption */
|
||||
#define CIPHER_SET_ALLOWWEAKCIPHER 0x20 /* allowWeakCipher is on */
|
||||
#define CIPHER_SET_DISALLOWWEAKCIPHER 0x40 /* allowWeakCipher is off */
|
||||
-
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
#define CIPHER_SET_DEFAULTWEAKDHPARAM 0x100 /* allowWeakDhParam is not set in cn=encryption */
|
||||
#define CIPHER_SET_ALLOWWEAKDHPARAM 0x200 /* allowWeakDhParam is on */
|
||||
#define CIPHER_SET_DISALLOWWEAKDHPARAM 0x400 /* allowWeakDhParam is off */
|
||||
-#endif
|
||||
+
|
||||
|
||||
#define CIPHER_SET_ISDEFAULT(flag) \
|
||||
(((flag)&CIPHER_SET_DEFAULT) ? PR_TRUE : PR_FALSE)
|
||||
@@ -145,10 +125,7 @@ static char *configDN = "cn=encryption,cn=config";
|
||||
#define CIPHER_IS_WEAK 0x4
|
||||
#define CIPHER_IS_DEPRECATED 0x8
|
||||
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
static int allowweakdhparam = CIPHER_SET_DEFAULTWEAKDHPARAM;
|
||||
-#endif
|
||||
-
|
||||
|
||||
static char **cipher_names = NULL;
|
||||
static char **enabled_cipher_names = NULL;
|
||||
@@ -225,12 +202,10 @@ static lookup_cipher _lookup_cipher[] = {
|
||||
/*{"tls_dhe_dss_1024_des_sha", ""}, */
|
||||
{"tls_dhe_dss_1024_rc4_sha", "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"},
|
||||
{"tls_dhe_dss_rc4_128_sha", "TLS_DHE_DSS_WITH_RC4_128_SHA"},
|
||||
-#if defined(NSS_TLS12)
|
||||
/* New in NSS 3.15 */
|
||||
{"tls_rsa_aes_128_gcm_sha", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
|
||||
{"tls_dhe_rsa_aes_128_gcm_sha", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
|
||||
{"tls_dhe_dss_aes_128_gcm_sha", NULL}, /* not available */
|
||||
-#endif
|
||||
{NULL, NULL}};
|
||||
|
||||
/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */
|
||||
@@ -317,7 +292,6 @@ getSupportedCiphers(void)
|
||||
SSLCipherSuiteInfo info;
|
||||
char *sep = "::";
|
||||
int number_of_ciphers = SSL_NumImplementedCiphers;
|
||||
- int i;
|
||||
int idx = 0;
|
||||
PRBool isFIPS = slapd_pk11_isFIPS();
|
||||
|
||||
@@ -325,7 +299,7 @@ getSupportedCiphers(void)
|
||||
|
||||
if ((cipher_names == NULL) && (_conf_ciphers)) {
|
||||
cipher_names = (char **)slapi_ch_calloc((number_of_ciphers + 1), sizeof(char *));
|
||||
- for (i = 0; _conf_ciphers[i].name != NULL; i++) {
|
||||
+ for (size_t i = 0; _conf_ciphers[i].name != NULL; i++) {
|
||||
SSL_GetCipherSuiteInfo((PRUint16)_conf_ciphers[i].num, &info, sizeof(info));
|
||||
/* only support FIPS approved ciphers in FIPS mode */
|
||||
if (!isFIPS || info.isFIPS) {
|
||||
@@ -341,7 +315,6 @@ getSupportedCiphers(void)
|
||||
return cipher_names;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
int
|
||||
get_allow_weak_dh_param(Slapi_Entry *e)
|
||||
{
|
||||
@@ -365,7 +338,6 @@ get_allow_weak_dh_param(Slapi_Entry *e)
|
||||
slapi_ch_free((void **)&val);
|
||||
return allow;
|
||||
}
|
||||
-#endif
|
||||
|
||||
|
||||
char **
|
||||
@@ -374,7 +346,6 @@ getEnabledCiphers(void)
|
||||
SSLCipherSuiteInfo info;
|
||||
char *sep = "::";
|
||||
int number_of_ciphers = 0;
|
||||
- int x;
|
||||
int idx = 0;
|
||||
PRBool enabled;
|
||||
|
||||
@@ -383,14 +354,14 @@ getEnabledCiphers(void)
|
||||
return NULL;
|
||||
}
|
||||
if ((enabled_cipher_names == NULL) && _conf_ciphers) {
|
||||
- for (x = 0; _conf_ciphers[x].name; x++) {
|
||||
+ for (size_t x = 0; _conf_ciphers[x].name; x++) {
|
||||
SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled);
|
||||
if (enabled) {
|
||||
number_of_ciphers++;
|
||||
}
|
||||
}
|
||||
enabled_cipher_names = (char **)slapi_ch_calloc((number_of_ciphers + 1), sizeof(char *));
|
||||
- for (x = 0; _conf_ciphers[x].name; x++) {
|
||||
+ for (size_t x = 0; _conf_ciphers[x].name; x++) {
|
||||
SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled);
|
||||
if (enabled) {
|
||||
SSL_GetCipherSuiteInfo((PRUint16)_conf_ciphers[x].num, &info, sizeof(info));
|
||||
@@ -472,9 +443,6 @@ getSSLVersionRange(char **min, char **max)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
-#if defined(NSS_TLS10)
|
||||
- return -1; /* not supported */
|
||||
-#else /* NSS_TLS11 or newer */
|
||||
if (min) {
|
||||
*min = slapi_getSSLVersion_str(slapdNSSVersions.min, NULL, 0);
|
||||
}
|
||||
@@ -482,10 +450,8 @@ getSSLVersionRange(char **min, char **max)
|
||||
*max = slapi_getSSLVersion_str(slapdNSSVersions.max, NULL, 0);
|
||||
}
|
||||
return 0;
|
||||
-#endif
|
||||
}
|
||||
|
||||
-#if defined(USE_OPENLDAP)
|
||||
void
|
||||
getSSLVersionRangeOL(int *min, int *max)
|
||||
{
|
||||
@@ -499,10 +465,7 @@ getSSLVersionRangeOL(int *min, int *max)
|
||||
if (!slapd_ssl_listener_is_initialized()) {
|
||||
return;
|
||||
}
|
||||
-#if defined(NSS_TLS10)
|
||||
- *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
|
||||
- return;
|
||||
-#else /* NSS_TLS11 or newer */
|
||||
+
|
||||
if (min) {
|
||||
switch (slapdNSSVersions.min) {
|
||||
case SSL_LIBRARY_VERSION_3_0:
|
||||
@@ -550,14 +513,11 @@ getSSLVersionRangeOL(int *min, int *max)
|
||||
}
|
||||
}
|
||||
return;
|
||||
-#endif
|
||||
}
|
||||
-#endif /* USE_OPENLDAP */
|
||||
|
||||
static void
|
||||
_conf_init_ciphers(void)
|
||||
{
|
||||
- int x;
|
||||
SECStatus rc;
|
||||
SSLCipherSuiteInfo info;
|
||||
const PRUint16 *implementedCiphers = SSL_GetImplementedCiphers();
|
||||
@@ -568,7 +528,7 @@ _conf_init_ciphers(void)
|
||||
}
|
||||
_conf_ciphers = (cipherstruct *)slapi_ch_calloc(SSL_NumImplementedCiphers + 1, sizeof(cipherstruct));
|
||||
|
||||
- for (x = 0; implementedCiphers && (x < SSL_NumImplementedCiphers); x++) {
|
||||
+ for (size_t x = 0; implementedCiphers && (x < SSL_NumImplementedCiphers); x++) {
|
||||
rc = SSL_GetCipherSuiteInfo(implementedCiphers[x], &info, sizeof info);
|
||||
if (SECFailure == rc) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, "Security Initialization",
|
||||
@@ -598,7 +558,6 @@ _conf_init_ciphers(void)
|
||||
static void
|
||||
_conf_setallciphers(int flag, char ***suplist, char ***unsuplist)
|
||||
{
|
||||
- int x;
|
||||
SECStatus rc;
|
||||
PRBool setdefault = CIPHER_SET_ISDEFAULT(flag);
|
||||
PRBool enabled = CIPHER_SET_ISALL(flag);
|
||||
@@ -608,7 +567,7 @@ _conf_setallciphers(int flag, char ***suplist, char ***unsuplist)
|
||||
|
||||
_conf_init_ciphers();
|
||||
|
||||
- for (x = 0; implementedCiphers && (x < SSL_NumImplementedCiphers); x++) {
|
||||
+ for (size_t x = 0; implementedCiphers && (x < SSL_NumImplementedCiphers); x++) {
|
||||
if (_conf_ciphers[x].flags & CIPHER_IS_DEFAULT) {
|
||||
/* certainly, not the first time. */
|
||||
setme = PR_TRUE;
|
||||
@@ -663,11 +622,10 @@ charray2str(char **ary, const char *delim)
|
||||
void
|
||||
_conf_dumpciphers(void)
|
||||
{
|
||||
- int x;
|
||||
PRBool enabled;
|
||||
/* {"SSL3","rc4", SSL_EN_RC4_128_WITH_MD5}, */
|
||||
slapd_SSL_info("Configured NSS Ciphers");
|
||||
- for (x = 0; _conf_ciphers[x].name; x++) {
|
||||
+ for (size_t x = 0; _conf_ciphers[x].name; x++) {
|
||||
SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled);
|
||||
if (enabled) {
|
||||
slapd_SSL_info("\t%s: enabled%s%s%s", _conf_ciphers[x].name,
|
||||
@@ -687,7 +645,8 @@ char *
|
||||
_conf_setciphers(char *setciphers, int flags)
|
||||
{
|
||||
char *t, err[MAGNUS_ERROR_LEN];
|
||||
- int x, i, active;
|
||||
+ int active;
|
||||
+ size_t x = 0;
|
||||
char *raw = setciphers;
|
||||
char **suplist = NULL;
|
||||
char **unsuplist = NULL;
|
||||
@@ -772,7 +731,7 @@ _conf_setciphers(char *setciphers, int flags)
|
||||
}
|
||||
}
|
||||
if (lookup) { /* lookup with old cipher name and get NSS cipherSuiteName */
|
||||
- for (i = 0; _lookup_cipher[i].alias; i++) {
|
||||
+ for (size_t i = 0; _lookup_cipher[i].alias; i++) {
|
||||
if (!PL_strcasecmp(setciphers, _lookup_cipher[i].alias)) {
|
||||
if (enabled && !_lookup_cipher[i].name[0]) {
|
||||
slapd_SSL_warn("Cipher suite %s is not available in NSS %d.%d. Ignoring %s",
|
||||
@@ -915,9 +874,8 @@ getChildren(char *dn)
|
||||
slapi_pblock_get(new_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result);
|
||||
slapi_pblock_get(new_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &e);
|
||||
if (e != NULL) {
|
||||
- int i;
|
||||
list = (char **)slapi_ch_malloc(sizeof(*list) * (nEntries + 1));
|
||||
- for (i = 0; e[i] != NULL; i++) {
|
||||
+ for (size_t i = 0; e[i] != NULL; i++) {
|
||||
list[i] = slapi_ch_strdup(slapi_entry_get_dn(e[i]));
|
||||
}
|
||||
list[nEntries] = NULL;
|
||||
@@ -935,8 +893,7 @@ static void
|
||||
freeChildren(char **list)
|
||||
{
|
||||
if (list != NULL) {
|
||||
- int i;
|
||||
- for (i = 0; list[i] != NULL; i++) {
|
||||
+ for (size_t i = 0; list[i] != NULL; i++) {
|
||||
slapi_ch_free((void **)(&list[i]));
|
||||
}
|
||||
slapi_ch_free((void **)(&list));
|
||||
@@ -1017,7 +974,6 @@ warn_if_no_key_file(const char *dir, int no_log)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
/*
|
||||
* If non NULL buf and positive bufsize is given,
|
||||
* the memory is used to store the version string.
|
||||
@@ -1183,7 +1139,6 @@ restrict_SSLVersionRange(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
|
||||
/*
|
||||
* slapd_nss_init() is always called from main(), even if we do not
|
||||
@@ -1206,7 +1161,6 @@ slapd_nss_init(int init_ssl __attribute__((unused)), int config_available __attr
|
||||
int create_certdb = 0;
|
||||
PRUint32 nssFlags = 0;
|
||||
char *certdir;
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
|
||||
/* Get the range of the supported SSL version */
|
||||
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
|
||||
@@ -1216,7 +1170,6 @@ slapd_nss_init(int init_ssl __attribute__((unused)), int config_available __attr
|
||||
slapi_log_err(SLAPI_LOG_CONFIG, "Security Initialization",
|
||||
"slapd_nss_init - Supported range by NSS: min: %s, max: %s\n",
|
||||
emin, emax);
|
||||
-#endif
|
||||
|
||||
/* set in slapd_bootstrap_config,
|
||||
thus certdir is available even if config_available is false */
|
||||
@@ -1385,9 +1338,7 @@ slapd_ssl_init()
|
||||
char *val = NULL;
|
||||
PK11SlotInfo *slot;
|
||||
Slapi_Entry *entry = NULL;
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
SECStatus rv = SECFailure;
|
||||
-#endif
|
||||
|
||||
/* Get general information */
|
||||
|
||||
@@ -1396,7 +1347,6 @@ slapd_ssl_init()
|
||||
val = slapi_entry_attr_get_charptr(entry, "nssslSessionTimeout");
|
||||
ciphers = slapi_entry_attr_get_charptr(entry, "nsssl3ciphers");
|
||||
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
allowweakdhparam = get_allow_weak_dh_param(entry);
|
||||
if (allowweakdhparam & CIPHER_SET_ALLOWWEAKDHPARAM) {
|
||||
slapd_SSL_warn("notice, generating new WEAK DH param");
|
||||
@@ -1405,7 +1355,6 @@ slapd_ssl_init()
|
||||
slapd_SSL_error("Warning, unable to generate weak dh parameters");
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
|
||||
/* We are currently using the value of sslSessionTimeout
|
||||
for ssl3SessionTimeout, see SSL_ConfigServerSessionIDCache() */
|
||||
@@ -1527,7 +1476,6 @@ slapd_ssl_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
/*
|
||||
* val: sslVersionMin/Max value set in cn=encription,cn=config (INPUT)
|
||||
* rval: Corresponding value to set SSLVersionRange (OUTPUT)
|
||||
@@ -1541,7 +1489,7 @@ static int
|
||||
set_NSS_version(char *val, PRUint16 *rval, int ismin)
|
||||
{
|
||||
char *vp, *endp;
|
||||
- int vnum;
|
||||
+ int64_t vnum;
|
||||
char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
|
||||
|
||||
if (NULL == rval) {
|
||||
@@ -1662,7 +1610,6 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin)
|
||||
}
|
||||
}
|
||||
} else if (tlsv < 1.3) { /* TLS1.2 */
|
||||
-#if defined(NSS_TLS12)
|
||||
if (ismin) {
|
||||
if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
slapd_SSL_warn("The value of sslVersionMin "
|
||||
@@ -1685,7 +1632,6 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin)
|
||||
(*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
} else { /* Specified TLS is newer than supported */
|
||||
if (ismin) {
|
||||
slapd_SSL_warn("The value of sslVersionMin "
|
||||
@@ -1720,7 +1666,6 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin)
|
||||
#undef SSLLEN
|
||||
#undef TLSSTR
|
||||
#undef TLSLEN
|
||||
-#endif
|
||||
|
||||
int
|
||||
slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
@@ -1740,12 +1685,10 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
char *tmpDir;
|
||||
Slapi_Entry *e = NULL;
|
||||
PRBool fipsMode = PR_FALSE;
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
PRUint16 NSSVersionMin = enabledNSSVersions.min;
|
||||
PRUint16 NSSVersionMax = enabledNSSVersions.max;
|
||||
char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
|
||||
char newmax[VERSION_STR_LENGTH];
|
||||
-#endif
|
||||
char cipher_string[1024];
|
||||
int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER;
|
||||
int_fast16_t renegotiation = (int_fast16_t)SSL_RENEGOTIATE_REQUIRES_XTN;
|
||||
@@ -1964,15 +1907,13 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
}
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
+ SSLKEAType certKEA;
|
||||
|
||||
-#ifdef HAVE_NSS_DHE
|
||||
- /* Step If we want weak dh params, flag it on the socket now! */
|
||||
-
|
||||
+ /* If we want weak dh params, flag it on the socket now! */
|
||||
rv = SSL_OptionSet(*fd, SSL_ENABLE_SERVER_DHE, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
slapd_SSL_warn("Warning, unable to start DHE");
|
||||
}
|
||||
-
|
||||
if (allowweakdhparam & CIPHER_SET_ALLOWWEAKDHPARAM) {
|
||||
slapd_SSL_warn("notice, allowing weak parameters on socket.");
|
||||
rv = SSL_EnableWeakDHEPrimeGroup(*fd, PR_TRUE);
|
||||
@@ -1980,13 +1921,9 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
slapd_SSL_warn("Warning, unable to allow weak DH params on socket.");
|
||||
}
|
||||
}
|
||||
-#endif
|
||||
|
||||
- if (slapd_pk11_fortezzaHasKEA(cert) == PR_TRUE) {
|
||||
- rv = SSL_ConfigSecureServer(*fd, cert, key, kt_fortezza);
|
||||
- } else {
|
||||
- rv = SSL_ConfigSecureServer(*fd, cert, key, kt_rsa);
|
||||
- }
|
||||
+ certKEA = NSS_FindCertKEAType(cert);
|
||||
+ rv = SSL_ConfigSecureServer(*fd, cert, key, certKEA);
|
||||
if (SECSuccess != rv) {
|
||||
errorCode = PR_GetError();
|
||||
slapd_SSL_warn("ConfigSecureServer: "
|
||||
@@ -2140,7 +2077,6 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
enableTLS1 = PR_TRUE; /* If available, enable TLS1 */
|
||||
}
|
||||
slapi_ch_free_string(&val);
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
val = slapi_entry_attr_get_charptr(e, "sslVersionMin");
|
||||
if (val) {
|
||||
(void)set_NSS_version(val, &NSSVersionMin, 1);
|
||||
@@ -2161,9 +2097,8 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
mymax, newmax);
|
||||
NSSVersionMax = enabledNSSVersions.max;
|
||||
}
|
||||
-#endif
|
||||
}
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
+
|
||||
if (NSSVersionMin > 0) {
|
||||
/* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
|
||||
slapdNSSVersions.min = NSSVersionMin;
|
||||
@@ -2183,7 +2118,6 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
mymin, mymax);
|
||||
}
|
||||
} else {
|
||||
-#endif
|
||||
/* deprecated code */
|
||||
sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
|
||||
if (sslStatus != SECSuccess) {
|
||||
@@ -2202,9 +2136,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
|
||||
enableTLS1 ? "enable" : "disable",
|
||||
errorCode, slapd_pr_strerror(errorCode));
|
||||
}
|
||||
-#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
|
||||
}
|
||||
-#endif
|
||||
|
||||
val = NULL;
|
||||
if (e != NULL) {
|
||||
@@ -2382,12 +2314,8 @@ slapd_SSL_client_auth(LDAP *ld)
|
||||
*/
|
||||
token = slapi_ch_strdup(internalTokenName);
|
||||
}
|
||||
-#if defined(USE_OPENLDAP)
|
||||
/* openldap needs tokenname:certnick */
|
||||
PR_snprintf(cert_name, sizeof(cert_name), "%s:%s", token, personality);
|
||||
-#else
|
||||
- PL_strncpyz(cert_name, personality, sizeof(cert_name));
|
||||
-#endif
|
||||
slapi_ch_free_string(&ssltoken);
|
||||
} else {
|
||||
/* external PKCS #11 token - attach token name */
|
||||
@@ -2461,7 +2389,6 @@ slapd_SSL_client_auth(LDAP *ld)
|
||||
"(no password). (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
|
||||
errorCode, slapd_pr_strerror(errorCode));
|
||||
} else {
|
||||
-#if defined(USE_OPENLDAP)
|
||||
if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) {
|
||||
char *certdir = config_get_certdir();
|
||||
char *keyfile = NULL;
|
||||
@@ -2532,29 +2459,6 @@ slapd_SSL_client_auth(LDAP *ld)
|
||||
cert_name);
|
||||
}
|
||||
}
|
||||
-/*
|
||||
- * not sure what else needs to be done for client auth - don't
|
||||
- * currently have a way to pass in the password to use to unlock
|
||||
- * the keydb - nor a way to disable caching
|
||||
- */
|
||||
-#else /* !USE_OPENLDAP */
|
||||
- rc = ldapssl_enable_clientauth(ld, SERVER_KEY_NAME, pw, cert_name);
|
||||
- if (rc != 0) {
|
||||
- errorCode = PR_GetError();
|
||||
- slapd_SSL_error("ldapssl_enable_clientauth(%s, %s) %i (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
|
||||
- SERVER_KEY_NAME, cert_name, rc,
|
||||
- errorCode, slapd_pr_strerror(errorCode));
|
||||
- } else {
|
||||
- /*
|
||||
- * We cannot allow NSS to cache outgoing client auth connections -
|
||||
- * each client auth connection must have it's own non-shared SSL
|
||||
- * connection to the peer so that it will go through the
|
||||
- * entire handshake protocol every time including the use of its
|
||||
- * own unique client cert - see bug 605457
|
||||
- */
|
||||
- ldapssl_set_option(ld, SSL_NO_CACHE, PR_TRUE);
|
||||
- }
|
||||
-#endif
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.17.0
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
From 240cfa58c62571b92640a385cfcce6d858cb00dc Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 30 May 2018 15:48:11 +0200
|
||||
Subject: [PATCH] Ticket 48184 - clean up and delete connections at shutdown
|
||||
(3rd)
|
||||
|
||||
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.
|
||||
|
||||
Fix Description:
|
||||
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
|
||||
|
||||
If it is not possible to schedule immediately a job it is sometime useless to wait:
|
||||
- if the connection is already freed, just cancel the scheduled job
|
||||
and do not register a new one
|
||||
- If we are in middle of a shutdown we do not know if the
|
||||
scheduled job is ns_handle_closure, so cancel the scheduled
|
||||
job and schedule ns_handle_closure.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48184
|
||||
|
||||
Reviewed by:
|
||||
Original fix reviewed by Ludwig and Viktor
|
||||
Second fix reviewed by Mark
|
||||
Third fix reviewed by Mark
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 10 +++--
|
||||
ldap/servers/slapd/conntable.c | 2 +-
|
||||
ldap/servers/slapd/daemon.c | 67 +++++++++++++++++++++++++--------
|
||||
ldap/servers/slapd/proto-slap.h | 2 +-
|
||||
4 files changed, 60 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 76e83112b..c54e7c26c 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -741,14 +741,18 @@ connection_acquire_nolock(Connection *conn)
|
||||
|
||||
/* returns non-0 if connection can be reused and 0 otherwise */
|
||||
int
|
||||
-connection_is_free(Connection *conn)
|
||||
+connection_is_free(Connection *conn, int use_lock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- PR_EnterMonitor(conn->c_mutex);
|
||||
+ if (use_lock) {
|
||||
+ PR_EnterMonitor(conn->c_mutex);
|
||||
+ }
|
||||
rc = conn->c_sd == SLAPD_INVALID_SOCKET && conn->c_refcnt == 0 &&
|
||||
!(conn->c_flags & CONN_FLAG_CLOSING);
|
||||
- PR_ExitMonitor(conn->c_mutex);
|
||||
+ if (use_lock) {
|
||||
+ PR_ExitMonitor(conn->c_mutex);
|
||||
+ }
|
||||
|
||||
return rc;
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||
index f2f763dfa..114871d17 100644
|
||||
--- a/ldap/servers/slapd/conntable.c
|
||||
+++ b/ldap/servers/slapd/conntable.c
|
||||
@@ -129,7 +129,7 @@ connection_table_get_connection(Connection_Table *ct, int sd)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (connection_is_free(&(ct->c[index]))) {
|
||||
+ if (connection_is_free(&(ct->c[index]), 1 /*use lock */)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index 50e67474e..35cfe7de0 100644
|
||||
--- a/ldap/servers/slapd/daemon.c
|
||||
+++ b/ldap/servers/slapd/daemon.c
|
||||
@@ -1699,7 +1699,8 @@ ns_connection_post_io_or_closing_try(Connection *conn)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Cancel any existing ns jobs we have registered.
|
||||
+ * A job was already scheduled.
|
||||
+ * Let it be dispatched first
|
||||
*/
|
||||
if (conn->c_job != NULL) {
|
||||
return 1;
|
||||
@@ -1780,25 +1781,59 @@ ns_connection_post_io_or_closing_try(Connection *conn)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Tries to schedule I/O for this connection
|
||||
+ * If the connection is already busy with a scheduled I/O
|
||||
+ * it can wait until scheduled I/O is dispatched
|
||||
+ *
|
||||
+ * caller must hold c_mutex
|
||||
+ */
|
||||
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);
|
||||
- }
|
||||
+ /* Here a job is currently scheduled (c->job is set) and not yet dispatched
|
||||
+ * Job can be either:
|
||||
+ * - ns_handle_closure
|
||||
+ * - ns_handle_pr_read_ready
|
||||
+ */
|
||||
+
|
||||
+ if (connection_is_free(conn, 0)) {
|
||||
+ PRStatus shutdown_status;
|
||||
+
|
||||
+ /* The connection being freed,
|
||||
+ * It means that ns_handle_closure already completed and the connection
|
||||
+ * is no longer on the active list.
|
||||
+ * The scheduled job is useless and scheduling a new one as well
|
||||
+ */
|
||||
+ shutdown_status = ns_job_done(conn->c_job);
|
||||
+ if (shutdown_status != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_CRIT, "ns_connection_post_io_or_closing", "Failed cancel a job on a freed connection %d !\n", conn->c_sd);
|
||||
+ }
|
||||
+ conn->c_job = NULL;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (g_get_shutdown() && CONN_NEEDS_CLOSING(conn)) {
|
||||
+ PRStatus shutdown_status;
|
||||
+
|
||||
+ /* This is shutting down cancel any scheduled job to register ns_handle_closure
|
||||
+ */
|
||||
+ shutdown_status = ns_job_done(conn->c_job);
|
||||
+ if (shutdown_status != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_CRIT, "ns_connection_post_io_or_closing", "Failed to cancel a job during shutdown %d !\n", conn->c_sd);
|
||||
+ }
|
||||
+ conn->c_job = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* We are not suppose to work immediately on the connection that is taken by
|
||||
+ * another job
|
||||
+ * release the lock and give some time
|
||||
+ */
|
||||
+ PR_ExitMonitor(conn->c_mutex);
|
||||
+ DS_Sleep(PR_MillisecondsToInterval(100));
|
||||
+ PR_EnterMonitor(conn->c_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index b13334ad1..f54bc6bc5 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -1431,7 +1431,7 @@ int connection_acquire_nolock(Connection *conn);
|
||||
int connection_acquire_nolock_ext(Connection *conn, int allow_when_closing);
|
||||
int connection_release_nolock(Connection *conn);
|
||||
int connection_release_nolock_ext(Connection *conn, int release_only);
|
||||
-int connection_is_free(Connection *conn);
|
||||
+int connection_is_free(Connection *conn, int user_lock);
|
||||
int connection_is_active_nolock(Connection *conn);
|
||||
#if defined(USE_OPENLDAP)
|
||||
ber_slen_t openldap_read_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len);
|
||||
--
|
||||
2.17.0
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue