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.6.1-24.el7_4
This commit is contained in:
parent
0c30787463
commit
b69e4737bd
89 changed files with 22919 additions and 5 deletions
1
.389-ds-base.metadata
Normal file
1
.389-ds-base.metadata
Normal file
|
@ -0,0 +1 @@
|
|||
debdbca81fda1651bf73e504ca8bc8c1b48a3b59 SOURCES/389-ds-base-1.3.6.1.tar.bz2
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
SOURCES/389-ds-base-1.3.6.1.tar.bz2
|
|
@ -1,5 +0,0 @@
|
|||
The master branch has no content
|
||||
|
||||
Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6
|
||||
|
||||
If you find this file in a distro specific branch, it means that no content has been checked in yet
|
|
@ -0,0 +1,67 @@
|
|||
From 70230bf894d9c0150dca8dc6fccc2712187f7b86 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 13 Mar 2017 13:29:43 +1000
|
||||
Subject: [PATCH 1/5] Ticket 49164 - Change NS to acq-rel semantics for atomics
|
||||
|
||||
Bug Description: We were using seq_cst to guarantee our operations
|
||||
as a poc. Changing to acq/rel allows us the same guarantees, but
|
||||
with less overheads.
|
||||
|
||||
Fix Description: Change the barrier type.
|
||||
|
||||
https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49164
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit b1b0574d2cdb012ab206999ed51f08d3340386ce)
|
||||
---
|
||||
src/nunc-stans/ns/ns_thrpool.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c
|
||||
index 744749b..a867b39 100644
|
||||
--- a/src/nunc-stans/ns/ns_thrpool.c
|
||||
+++ b/src/nunc-stans/ns/ns_thrpool.c
|
||||
@@ -167,7 +167,7 @@ ns_thrpool_is_shutdown(struct ns_thrpool_t *tp)
|
||||
{
|
||||
/* We need to barrier this somehow? */
|
||||
int32_t result = 0;
|
||||
- __atomic_load(&(tp->shutdown), &result, __ATOMIC_SEQ_CST);
|
||||
+ __atomic_load(&(tp->shutdown), &result, __ATOMIC_ACQUIRE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ ns_thrpool_is_event_shutdown(struct ns_thrpool_t *tp)
|
||||
{
|
||||
/* We need to barrier this somehow? */
|
||||
int32_t result = 0;
|
||||
- __atomic_load(&(tp->shutdown_event_loop), &result, __ATOMIC_SEQ_CST);
|
||||
+ __atomic_load(&(tp->shutdown_event_loop), &result, __ATOMIC_ACQUIRE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1402,7 +1402,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp)
|
||||
#endif
|
||||
if (tp) {
|
||||
/* Set the flag to shutdown the event loop. */
|
||||
- __atomic_add_fetch(&(tp->shutdown_event_loop), 1, __ATOMIC_SEQ_CST);
|
||||
+ __atomic_add_fetch(&(tp->shutdown_event_loop), 1, __ATOMIC_RELEASE);
|
||||
|
||||
/* Finish the event queue wakeup job. This has the
|
||||
* side effect of waking up the event loop thread, which
|
||||
@@ -1491,7 +1491,7 @@ ns_thrpool_shutdown(struct ns_thrpool_t *tp)
|
||||
}
|
||||
/* Set the shutdown flag. This will cause the worker
|
||||
* threads to exit after they finish all remaining work. */
|
||||
- __atomic_add_fetch(&(tp->shutdown), 1, __ATOMIC_SEQ_CST);
|
||||
+ __atomic_add_fetch(&(tp->shutdown), 1, __ATOMIC_RELEASE);
|
||||
|
||||
/* Wake up the idle worker threads so they can exit. */
|
||||
pthread_mutex_lock(&(tp->work_q_lock));
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
From a00917eec0bcef75180eaf4dd9b360519b9e2644 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 14:35:05 -0400
|
||||
Subject: [PATCH 2/5] Issue 49170 - sync plugin thread count not handled
|
||||
correctly
|
||||
|
||||
Bug Description: If sync repl connections get aborted the thread_count is
|
||||
not properly updated which leads to the server hanging
|
||||
on shutdown.
|
||||
|
||||
Fix Description: When connections get aborted we still need to shutdown
|
||||
the result thread cleanly: remove the req, update thread
|
||||
count, etc.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49170
|
||||
|
||||
Reviewed by: nhosoi(Thanks!)
|
||||
|
||||
(cherry picked from commit 770fcf4349ccf9e07ff0e1cf0d6991927ec9ba75)
|
||||
---
|
||||
ldap/servers/plugins/sync/sync_persist.c | 17 ++++++++---------
|
||||
1 file changed, 8 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
|
||||
index d0c8da2..667a529 100644
|
||||
--- a/ldap/servers/plugins/sync/sync_persist.c
|
||||
+++ b/ldap/servers/plugins/sync/sync_persist.c
|
||||
@@ -548,16 +548,16 @@ sync_send_results( void *arg )
|
||||
slapi_pblock_get(req->req_pblock, SLAPI_CONNECTION, &conn);
|
||||
if (NULL == conn) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM,
|
||||
- "sync_send_results - conn=%" NSPRIu64 " op=%d Null connection - aborted\n",
|
||||
- connid, opid);
|
||||
- return;
|
||||
+ "sync_send_results - conn=%" NSPRIu64 " op=%d Null connection - aborted\n",
|
||||
+ connid, opid);
|
||||
+ goto done;
|
||||
}
|
||||
conn_acq_flag = sync_acquire_connection (conn);
|
||||
if (conn_acq_flag) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM,
|
||||
- "sync_send_results - conn=%" NSPRIu64 " op=%d Could not acquire the connection - aborted\n",
|
||||
- connid, opid);
|
||||
- return;
|
||||
+ "sync_send_results - conn=%" NSPRIu64 " op=%d Could not acquire the connection - aborted\n",
|
||||
+ connid, opid);
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
PR_Lock( sync_request_list->sync_req_cvarlock );
|
||||
@@ -658,15 +658,14 @@ sync_send_results( void *arg )
|
||||
}
|
||||
}
|
||||
PR_Unlock( sync_request_list->sync_req_cvarlock );
|
||||
- sync_remove_request( req );
|
||||
|
||||
/* indicate the end of search */
|
||||
-
|
||||
sync_release_connection(req->req_pblock, conn, op, conn_acq_flag == 0);
|
||||
|
||||
+done:
|
||||
+ sync_remove_request( req );
|
||||
PR_DestroyLock ( req->req_lock );
|
||||
req->req_lock = NULL;
|
||||
-
|
||||
slapi_ch_free((void **) &req->req_pblock );
|
||||
slapi_ch_free((void **) &req->req_orig_base );
|
||||
slapi_filter_free(req->req_filter, 1);
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
From 22f1ff8d87a7daf9fbbe2ddfbd195a6bfdae1cd6 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 14:01:33 +1000
|
||||
Subject: [PATCH 3/5] Ticket 49165 pw_verify did not handle external auth
|
||||
|
||||
Bug Description: During the change to improve sasl and simple bind,
|
||||
we externalised the backend selection outside of do_bind. In an
|
||||
auto_bind scenario however, this mean the be was null, causing the
|
||||
dn to always be invalidated.
|
||||
|
||||
Fix Description: Add a pw_validate_be_dn function, that correctly
|
||||
checks if we are anonymous, a real be dn, or rootdn. This then allows
|
||||
the correct authentication of autobinds.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49165
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit 8dbfff1ff4152afb018490886a612c448ea2a1b0)
|
||||
---
|
||||
ldap/servers/slapd/bind.c | 9 +++++--
|
||||
ldap/servers/slapd/dn.c | 5 ++++
|
||||
ldap/servers/slapd/pw_verify.c | 57 +++++++++++++++++++++++++++++++++++++--
|
||||
ldap/servers/slapd/pw_verify.h | 1 +
|
||||
ldap/servers/slapd/slapi-plugin.h | 9 +++++++
|
||||
5 files changed, 77 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
||||
index b4bb363..5c4fada 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -656,7 +656,12 @@ do_bind( Slapi_PBlock *pb )
|
||||
/* We could be serving multiple database backends. Select the appropriate one */
|
||||
/* pw_verify_be_dn will select the backend we need for us. */
|
||||
|
||||
- rc = pw_verify_be_dn(pb, &referral);
|
||||
+ if (auto_bind) {
|
||||
+ /* We have no password material. We should just check who we are binding as. */
|
||||
+ rc = pw_validate_be_dn(pb, &referral);
|
||||
+ } else {
|
||||
+ rc = pw_verify_be_dn(pb, &referral);
|
||||
+ }
|
||||
|
||||
if (rc == SLAPI_BIND_NO_BACKEND) {
|
||||
send_nobackend_ldap_result( pb );
|
||||
@@ -715,7 +720,7 @@ do_bind( Slapi_PBlock *pb )
|
||||
*
|
||||
*/
|
||||
slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
||||
- if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
||||
+ if (!isroot && !slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
||||
bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
||||
myrc = slapi_check_account_lock(pb, bind_target_entry, pw_response_requested, 1, 1);
|
||||
if (1 == myrc) { /* account is locked */
|
||||
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
|
||||
index d043f2a..fa3909f 100644
|
||||
--- a/ldap/servers/slapd/dn.c
|
||||
+++ b/ldap/servers/slapd/dn.c
|
||||
@@ -1738,6 +1738,11 @@ slapi_dn_isroot( const char *dn )
|
||||
return( rc );
|
||||
}
|
||||
|
||||
+int32_t
|
||||
+slapi_sdn_isroot(const Slapi_DN *sdn) {
|
||||
+ return slapi_dn_isroot(slapi_sdn_get_ndn(sdn));
|
||||
+}
|
||||
+
|
||||
int
|
||||
slapi_is_rootdse( const char *dn )
|
||||
{
|
||||
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
||||
index 93e5ff3..529bb83 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.c
|
||||
+++ b/ldap/servers/slapd/pw_verify.c
|
||||
@@ -88,8 +88,61 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Resolve the dn we have been requested to bind with and verify it's
|
||||
+ * valid, and has a backend.
|
||||
+ *
|
||||
+ * We are checking:
|
||||
+ * * is this anonymous?
|
||||
+ * * is this the rootdn?
|
||||
+ * * is this a real dn, which associates to a real backend.
|
||||
+ *
|
||||
+ * This is used in SASL autobinds, so we need to handle this validation.
|
||||
+ */
|
||||
+
|
||||
int
|
||||
-pw_verify_dn()
|
||||
+pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
{
|
||||
- return LDAP_OPERATIONS_ERROR;
|
||||
+ int rc = 0;
|
||||
+ Slapi_Backend *be = NULL;
|
||||
+ Slapi_DN *pb_sdn;
|
||||
+ struct berval *cred;
|
||||
+ ber_tag_t method;
|
||||
+
|
||||
+
|
||||
+ slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
|
||||
+ slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &cred);
|
||||
+ slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method);
|
||||
+
|
||||
+ if (pb_sdn != NULL || cred != NULL) {
|
||||
+ return LDAP_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (*referral) {
|
||||
+ return SLAPI_BIND_REFERRAL;
|
||||
+ }
|
||||
+
|
||||
+ /* We need a slapi_sdn_isanon? */
|
||||
+ if (method == LDAP_AUTH_SIMPLE && cred->bv_len == 0) {
|
||||
+ return SLAPI_BIND_ANONYMOUS;
|
||||
+ }
|
||||
+
|
||||
+ if (slapi_sdn_isroot(pb_sdn)) {
|
||||
+ /* This is a real identity */
|
||||
+ return SLAPI_BIND_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
||||
+ return SLAPI_BIND_NO_BACKEND;
|
||||
+ }
|
||||
+ slapi_be_Unlock(be);
|
||||
+
|
||||
+ slapi_pblock_set(pb, SLAPI_BACKEND, be);
|
||||
+ slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
|
||||
+ /* Make sure the result handlers are setup */
|
||||
+ set_db_default_result_handlers(pb);
|
||||
+
|
||||
+ /* The backend associated with this identity is real. */
|
||||
+
|
||||
+ return SLAPI_BIND_SUCCESS;
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/pw_verify.h b/ldap/servers/slapd/pw_verify.h
|
||||
index fc34fd1..5137027 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.h
|
||||
+++ b/ldap/servers/slapd/pw_verify.h
|
||||
@@ -11,5 +11,6 @@
|
||||
|
||||
int pw_verify_root_dn(const char *dn, const Slapi_Value *cred);
|
||||
int pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral);
|
||||
+int pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral);
|
||||
|
||||
#endif /* _SLAPD_PW_VERIFY_H_ */
|
||||
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
||||
index b223f65..1bd8fc8 100644
|
||||
--- a/ldap/servers/slapd/slapi-plugin.h
|
||||
+++ b/ldap/servers/slapd/slapi-plugin.h
|
||||
@@ -3800,6 +3800,15 @@ int slapi_dn_isparent( const char *parentdn, const char *childdn );
|
||||
int slapi_dn_isroot( const char *dn );
|
||||
|
||||
/**
|
||||
+ * Determines if an SDN is the root DN.
|
||||
+ *
|
||||
+ * \param sdn The DN to check
|
||||
+ * \return \c 1 if the DN is the root DN.
|
||||
+ * \return \c 0 if the DN is not the root DN.
|
||||
+ */
|
||||
+int32_t slapi_sdn_isroot( const Slapi_DN *sdn );
|
||||
+
|
||||
+/**
|
||||
* Checks if a DN is the backend suffix.
|
||||
*
|
||||
* \param pb A parameter block with the backend set.
|
||||
--
|
||||
2.9.3
|
||||
|
266
SOURCES/0003-Issue-49169-Fix-covscan-errors.patch
Normal file
266
SOURCES/0003-Issue-49169-Fix-covscan-errors.patch
Normal file
|
@ -0,0 +1,266 @@
|
|||
From 97f09918ef370c3be5aa64dcfeb3bb21e762f90d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 20:23:07 -0400
|
||||
Subject: [PATCH 4/5] Issue 49169 - Fix covscan errors
|
||||
|
||||
src/libsds/bpt/map.c - resource leak
|
||||
ldap/servers/slapd/vattr.c - resource leak
|
||||
ldap/servers/slapd/task.c: resource leaks
|
||||
ldap/servers/slapd/str2filter.c - resource leak
|
||||
ldap/servers/slapd/pw.c - resource leak
|
||||
ldap/servers/slapd/back-ldbm/import-threads.c - resource leak
|
||||
ldap/servers/plugins/uiduniq/uid.c:536 - resource leak
|
||||
ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c:164 - resource leak
|
||||
ldap/servers/plugins/linkedattrs/linked_attrs.c:1672 - resource leak
|
||||
ldap/servers/plugins/addn/addn.c:419
|
||||
ldap/servers/slapd/ssl.c - dead code
|
||||
ldap/servers/slapd/index_subsystem.c - null dereference
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49169
|
||||
|
||||
Reviewed by: nkinder & wibrown(Thanks!!)
|
||||
|
||||
(cherry picked from commit c75126be1edece121826e336141f9b0b9c0bddfd)
|
||||
---
|
||||
ldap/servers/plugins/addn/addn.c | 4 +++-
|
||||
ldap/servers/plugins/linkedattrs/linked_attrs.c | 2 ++
|
||||
ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c | 1 +
|
||||
ldap/servers/plugins/uiduniq/uid.c | 6 +++++-
|
||||
ldap/servers/slapd/back-ldbm/import-threads.c | 1 +
|
||||
ldap/servers/slapd/index_subsystem.c | 27 +++++++++++++------------
|
||||
ldap/servers/slapd/pw.c | 1 +
|
||||
ldap/servers/slapd/pw_verify.c | 1 -
|
||||
ldap/servers/slapd/ssl.c | 8 +++-----
|
||||
ldap/servers/slapd/str2filter.c | 1 +
|
||||
ldap/servers/slapd/task.c | 3 +--
|
||||
ldap/servers/slapd/vattr.c | 6 +++---
|
||||
src/libsds/sds/bpt/map.c | 1 +
|
||||
13 files changed, 36 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/addn/addn.c b/ldap/servers/plugins/addn/addn.c
|
||||
index 3abc112..6ba7833 100644
|
||||
--- a/ldap/servers/plugins/addn/addn.c
|
||||
+++ b/ldap/servers/plugins/addn/addn.c
|
||||
@@ -415,7 +415,9 @@ addn_start(Slapi_PBlock *pb)
|
||||
domain = slapi_entry_attr_get_charptr(plugin_entry, "addn_default_domain");
|
||||
|
||||
if (domain == NULL) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, plugin_name, "addn_start: CRITICAL: No default domain in configuration, you must set addn_default_domain!\n");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, plugin_name,
|
||||
+ "addn_start: CRITICAL: No default domain in configuration, you must set addn_default_domain!\n");
|
||||
+ slapi_ch_free((void**)&config);
|
||||
return SLAPI_PLUGIN_FAILURE;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c
|
||||
index b5adb21..d046542 100644
|
||||
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c
|
||||
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c
|
||||
@@ -1669,6 +1669,8 @@ linked_attrs_mod_post_op(Slapi_PBlock *pb)
|
||||
/* Bail out if the plug-in close function was just called. */
|
||||
if (!slapi_plugin_running(pb)) {
|
||||
linked_attrs_unlock();
|
||||
+ slapi_mod_free(&next_mod);
|
||||
+ slapi_mods_free(&smods);
|
||||
return SLAPI_PLUGIN_SUCCESS;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c b/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
|
||||
index 1b3e555..b228700 100644
|
||||
--- a/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
|
||||
+++ b/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
|
||||
@@ -161,6 +161,7 @@ pbkdf2_sha256_pw_enc(const char *pwd)
|
||||
*/
|
||||
if ( pbkdf2_sha256_hash(hash + PBKDF2_ITERATIONS_LENGTH + PBKDF2_SALT_LENGTH, PBKDF2_HASH_LENGTH, &passItem, &saltItem, PBKDF2_ITERATIONS) != SECSuccess ) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, (char *)schemeName, "Could not generate pbkdf2_sha256_hash!\n");
|
||||
+ slapi_ch_free_string(&enc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
|
||||
index ae9320e..46554b2 100644
|
||||
--- a/ldap/servers/plugins/uiduniq/uid.c
|
||||
+++ b/ldap/servers/plugins/uiduniq/uid.c
|
||||
@@ -533,7 +533,11 @@ create_filter(const char **attributes, const struct berval *value, const char *r
|
||||
|
||||
/* Place value in filter */
|
||||
if (ldap_quote_filter_value(value->bv_val, value->bv_len,
|
||||
- fp, max-fp, &valueLen)) { slapi_ch_free((void**)&filter); return 0; }
|
||||
+ fp, max-fp, &valueLen)) {
|
||||
+ slapi_ch_free((void**)&filter);
|
||||
+ slapi_ch_free((void**)&attrLen);
|
||||
+ return 0;
|
||||
+ }
|
||||
fp += valueLen;
|
||||
|
||||
strcpy(fp, ")");
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
|
||||
index 5b81427..087103b 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
|
||||
@@ -1647,6 +1647,7 @@ upgradedn_producer(void *param)
|
||||
}
|
||||
e = slapi_str2entry_ext(normdn, NULL, data.dptr,
|
||||
SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT);
|
||||
+ slapi_ch_free_string(&rdn);
|
||||
}
|
||||
} else {
|
||||
e =
|
||||
diff --git a/ldap/servers/slapd/index_subsystem.c b/ldap/servers/slapd/index_subsystem.c
|
||||
index 57d4f58..8f9fe6d 100644
|
||||
--- a/ldap/servers/slapd/index_subsystem.c
|
||||
+++ b/ldap/servers/slapd/index_subsystem.c
|
||||
@@ -185,27 +185,28 @@ static int index_subsys_index_matches_filter(indexEntry *index, Slapi_Filter *f)
|
||||
*/
|
||||
int index_subsys_assign_filter_decoders(Slapi_PBlock *pb)
|
||||
{
|
||||
- int rc;
|
||||
+ int rc = 0;
|
||||
Slapi_Filter *f;
|
||||
char *subsystem = "index_subsys_assign_filter_decoders";
|
||||
char logbuf[ 1024 ];
|
||||
|
||||
/* extract the filter */
|
||||
slapi_pblock_get(pb, SLAPI_SEARCH_FILTER, &f);
|
||||
+ if (f) {
|
||||
+ if ( loglevel_is_set( LDAP_DEBUG_FILTER )) {
|
||||
+ logbuf[0] = '\0';
|
||||
+ slapi_log_err(SLAPI_LOG_DEBUG, subsystem, "before: %s\n",
|
||||
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
+ }
|
||||
|
||||
- if ( loglevel_is_set( LDAP_DEBUG_FILTER ) && NULL != f ) {
|
||||
- logbuf[0] = '\0';
|
||||
- slapi_log_err(SLAPI_LOG_DEBUG, subsystem, "before: %s\n",
|
||||
- slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
- }
|
||||
-
|
||||
- /* find decoders */
|
||||
- rc = index_subsys_assign_decoders(f);
|
||||
+ /* find decoders */
|
||||
+ rc = index_subsys_assign_decoders(f);
|
||||
|
||||
- if ( loglevel_is_set( LDAP_DEBUG_FILTER ) && NULL != f ) {
|
||||
- logbuf[0] = '\0';
|
||||
- slapi_log_err(SLAPI_LOG_DEBUG, subsystem, " after: %s\n",
|
||||
- slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
+ if ( loglevel_is_set( LDAP_DEBUG_FILTER )) {
|
||||
+ logbuf[0] = '\0';
|
||||
+ slapi_log_err(SLAPI_LOG_DEBUG, subsystem, " after: %s\n",
|
||||
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
|
||||
+ }
|
||||
}
|
||||
|
||||
return rc;
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index 215c9eb..378d148 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -1512,6 +1512,7 @@ check_trivial_words (Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char
|
||||
ep = sp + strlen(sp);
|
||||
ep = ldap_utf8prevn(sp, ep, toklen);
|
||||
if (!ep || (sp >= ep)) {
|
||||
+ slapi_ch_free_string(&sp);
|
||||
continue;
|
||||
}
|
||||
/* See if the password contains the value */
|
||||
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
||||
index 529bb83..a9fd9ec 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.c
|
||||
+++ b/ldap/servers/slapd/pw_verify.c
|
||||
@@ -103,7 +103,6 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
int
|
||||
pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
{
|
||||
- int rc = 0;
|
||||
Slapi_Backend *be = NULL;
|
||||
Slapi_DN *pb_sdn;
|
||||
struct berval *cred;
|
||||
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
|
||||
index f35b3f1..050e7b5 100644
|
||||
--- a/ldap/servers/slapd/ssl.c
|
||||
+++ b/ldap/servers/slapd/ssl.c
|
||||
@@ -1418,12 +1418,10 @@ slapd_ssl_init()
|
||||
errorCode = PR_GetError();
|
||||
slapd_SSL_error("Failed to retrieve SSL "
|
||||
"configuration information ("
|
||||
- SLAPI_COMPONENT_NAME_NSPR " error %d - %s): "
|
||||
+ SLAPI_COMPONENT_NAME_NSPR " error %d - not found): "
|
||||
"nssslSessionTimeout: %s ",
|
||||
- errorCode, slapd_pr_strerror(errorCode),
|
||||
- (val ? "found" : "not found"));
|
||||
- slapi_ch_free((void **) &val);
|
||||
- slapi_ch_free((void **) &ciphers);
|
||||
+ errorCode, slapd_pr_strerror(errorCode));
|
||||
+ slapi_ch_free((void **)&ciphers);
|
||||
freeConfigEntry( &entry );
|
||||
return -1;
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/str2filter.c b/ldap/servers/slapd/str2filter.c
|
||||
index ebd5c5d..744c93f 100644
|
||||
--- a/ldap/servers/slapd/str2filter.c
|
||||
+++ b/ldap/servers/slapd/str2filter.c
|
||||
@@ -344,6 +344,7 @@ str2simple( char *str , int unescape_filter)
|
||||
*endp = '\0';
|
||||
rc = _parse_ext_filter(str, extp, &f->f_mr_type, &f->f_mr_oid, &f->f_mr_dnAttrs);
|
||||
if (rc) {
|
||||
+ slapi_filter_free(f, 1);
|
||||
return NULL; /* error */
|
||||
} else {
|
||||
f->f_choice = LDAP_FILTER_EXTENDED;
|
||||
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
|
||||
index ad52e9d..eabd517 100644
|
||||
--- a/ldap/servers/slapd/task.c
|
||||
+++ b/ldap/servers/slapd/task.c
|
||||
@@ -2389,7 +2389,6 @@ task_fixup_tombstones_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
|
||||
slapi_task_finish(task, *returncode);
|
||||
slapi_ch_array_free(base);
|
||||
slapi_ch_free((void **)&task_data);
|
||||
- return SLAPI_DSE_CALLBACK_ERROR;
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -2507,9 +2506,9 @@ task_des2aes(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
|
||||
error:
|
||||
if (rc == SLAPI_DSE_CALLBACK_ERROR){
|
||||
slapi_ch_array_free(bases);
|
||||
- slapi_ch_array_free(suffix);
|
||||
slapi_ch_free((void **)&task_data);
|
||||
}
|
||||
+ slapi_ch_array_free(suffix);
|
||||
return rc;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||||
index 34665de..599b54e 100644
|
||||
--- a/ldap/servers/slapd/vattr.c
|
||||
+++ b/ldap/servers/slapd/vattr.c
|
||||
@@ -753,10 +753,10 @@ slapi_vattr_values_get_sp(vattr_context *c,
|
||||
}
|
||||
if (use_local_ctx) {
|
||||
/* slapi_pblock_destroy cleans up pb_vattr_context, as well */
|
||||
- slapi_pblock_destroy(local_pb);
|
||||
- } else {
|
||||
- vattr_context_ungrok(&c);
|
||||
+ slapi_pblock_destroy(local_pb);
|
||||
+ ctx->pb = NULL;
|
||||
}
|
||||
+ vattr_context_ungrok(&ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
diff --git a/src/libsds/sds/bpt/map.c b/src/libsds/sds/bpt/map.c
|
||||
index 4205aa5..2c3468b 100644
|
||||
--- a/src/libsds/sds/bpt/map.c
|
||||
+++ b/src/libsds/sds/bpt/map.c
|
||||
@@ -18,6 +18,7 @@ sds_bptree_map_nodes(sds_bptree_instance *binst, sds_bptree_node *root, sds_resu
|
||||
sds_bptree_node_list *tail = cur;
|
||||
|
||||
if (binst == NULL) {
|
||||
+ sds_free(cur);
|
||||
return SDS_NULL_POINTER;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
From 645e628626f4a3d4b662c067584b4efc6b5c70c5 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 10:46:38 +1000
|
||||
Subject: [PATCH 5/5] Ticket 49171 - Nunc Stans incorrectly reports a timeout
|
||||
|
||||
Bug Description: In some cases nunc-stans would incorrectly report
|
||||
and IO timeout.
|
||||
|
||||
Fix Description: Make the io output type volatile to prevent re-arranging
|
||||
of the code. We then make timeout exclusive to read, write and signal.
|
||||
Finally, we add an extra check into ns_handle_pr_read_ready that
|
||||
asserts we truly have an idle timeout. It issues a warning now
|
||||
instead if this scenario occurs, rather than closing the
|
||||
connection.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49171
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (thanks!)
|
||||
|
||||
(cherry picked from commit c8ce1b32cc365174c8280111c2d55bba45f7949f)
|
||||
---
|
||||
ldap/servers/slapd/daemon.c | 15 +++++++++++----
|
||||
src/nunc-stans/ns/ns_event_fw_event.c | 28 ++++++++++++++++------------
|
||||
2 files changed, 27 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index a37c8c6..6b3331d 100644
|
||||
--- a/ldap/servers/slapd/daemon.c
|
||||
+++ b/ldap/servers/slapd/daemon.c
|
||||
@@ -1970,11 +1970,18 @@ ns_handle_pr_read_ready(struct ns_job_t *job)
|
||||
connection_release_nolock_ext(c, 1); /* release ref acquired when job was added */
|
||||
if (CONN_NEEDS_CLOSING(c)) {
|
||||
ns_handle_closure_nomutex(c);
|
||||
+ /* We shouldn't need the c_idletimeout check here because of how libevent works.
|
||||
+ * consider testing this and removing it oneday.
|
||||
+ */
|
||||
} else if (NS_JOB_IS_TIMER(ns_job_get_output_type(job))) {
|
||||
- /* idle timeout */
|
||||
- disconnect_server_nomutex_ext(c, c->c_connid, -1,
|
||||
- SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN,
|
||||
- 0 /* do not schedule closure, do it next */);
|
||||
+ if (c->c_idletimeout > 0) {
|
||||
+ /* idle timeout */
|
||||
+ disconnect_server_nomutex_ext(c, c->c_connid, -1,
|
||||
+ SLAPD_DISCONNECT_IDLE_TIMEOUT, EAGAIN,
|
||||
+ 0 /* do not schedule closure, do it next */);
|
||||
+ } else {
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ns_handle_pr_read_ready", "Received idletime out with c->c_idletimeout as 0. Ignoring.\n");
|
||||
+ }
|
||||
ns_handle_closure_nomutex(c);
|
||||
} else if ((connection_activity(c, maxthreads)) == -1) {
|
||||
/* This might happen as a result of
|
||||
diff --git a/src/nunc-stans/ns/ns_event_fw_event.c b/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
index 58dac28..3acbaf7 100644
|
||||
--- a/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
+++ b/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
@@ -71,18 +71,22 @@ event_logger_cb(int severity, const char *msg)
|
||||
static ns_job_type_t
|
||||
event_flags_to_type(short events)
|
||||
{
|
||||
- ns_job_type_t job_type = 0;
|
||||
- if (events & EV_READ) {
|
||||
- job_type |= NS_JOB_READ;
|
||||
- }
|
||||
- if (events & EV_WRITE) {
|
||||
- job_type |= NS_JOB_WRITE;
|
||||
- }
|
||||
- if (events & EV_TIMEOUT) {
|
||||
- job_type |= NS_JOB_TIMER;
|
||||
- }
|
||||
- if (events & EV_SIGNAL) {
|
||||
- job_type |= NS_JOB_SIGNAL;
|
||||
+ /* The volatile here prevents gcc rearranging this code within the thread. */
|
||||
+ volatile ns_job_type_t job_type = 0;
|
||||
+
|
||||
+ /* Either we timeout *or* we are a real event */
|
||||
+ if (!(events & EV_TIMEOUT)) {
|
||||
+ if (events & EV_READ) {
|
||||
+ job_type |= NS_JOB_READ;
|
||||
+ }
|
||||
+ if (events & EV_WRITE) {
|
||||
+ job_type |= NS_JOB_WRITE;
|
||||
+ }
|
||||
+ if (events & EV_SIGNAL) {
|
||||
+ job_type |= NS_JOB_SIGNAL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ job_type = NS_JOB_TIMER;
|
||||
}
|
||||
return job_type;
|
||||
}
|
||||
--
|
||||
2.9.3
|
||||
|
36
SOURCES/0005-Issue-49169-Fix-covscan-errors-regression.patch
Normal file
36
SOURCES/0005-Issue-49169-Fix-covscan-errors-regression.patch
Normal file
|
@ -0,0 +1,36 @@
|
|||
From 6dde613c1a44731e017d262c2b5868dbe333da74 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 09:00:19 -0400
|
||||
Subject: [PATCH] Issue 49169 - Fix covscan errors(regression)
|
||||
|
||||
Description: The change to vattr.c caused problems with the tests.
|
||||
Removing change.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49169
|
||||
|
||||
Reviewed by: one line commit rule
|
||||
|
||||
(cherry picked from commit 314e9ecf310d4ab8e8fc700bd5d3477d52e4fa19)
|
||||
---
|
||||
ldap/servers/slapd/vattr.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||||
index 599b54e..ef4d7f2 100644
|
||||
--- a/ldap/servers/slapd/vattr.c
|
||||
+++ b/ldap/servers/slapd/vattr.c
|
||||
@@ -754,9 +754,9 @@ slapi_vattr_values_get_sp(vattr_context *c,
|
||||
if (use_local_ctx) {
|
||||
/* slapi_pblock_destroy cleans up pb_vattr_context, as well */
|
||||
slapi_pblock_destroy(local_pb);
|
||||
- ctx->pb = NULL;
|
||||
+ } else {
|
||||
+ vattr_context_ungrok(&c);
|
||||
}
|
||||
- vattr_context_ungrok(&ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
From 310b8f8b3c59423b9dfa3a6ea30f4a719f342fc9 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 1 Mar 2017 10:56:40 -0500
|
||||
Subject: [PATCH] Issue 49062 - Reset agmt update staus and total init
|
||||
|
||||
Description: Make sure we always reset the agmt status after doing a reinit
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49062
|
||||
|
||||
Reviewed by: tbordaz & nhosoi(Thanks!!)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_tot_protocol.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
||||
index 57d9de2..45a084a 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
||||
@@ -591,6 +591,7 @@ retry:
|
||||
"\"%s\". Sent %lu entries.\n",
|
||||
agmt_get_long_name(prp->agmt), cb_data.num_entries);
|
||||
agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total update succeeded");
|
||||
+ agmt_set_last_update_status(prp->agmt, 0, 0, NULL);
|
||||
}
|
||||
|
||||
done:
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
From edf3d210e9ba9006f87e0597b052fa925c68ddc2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 20 Mar 2017 17:35:10 -0400
|
||||
Subject: [PATCH] Issue 49065 - dbmon.sh fails if you have
|
||||
nsslapd-require-secure-binds enabled
|
||||
|
||||
Description: Add the ability to detect if security is enabled, if so connect using
|
||||
start TLS. Added a new param SERVID for specifying which instance
|
||||
you want to look at.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49065
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
ldap/admin/src/scripts/{dbmon.sh => dbmon.sh.in} | 62 ++++++++++++++++++++++--
|
||||
man/man8/dbmon.sh.8 | 14 +++---
|
||||
3 files changed, 65 insertions(+), 13 deletions(-)
|
||||
rename ldap/admin/src/scripts/{dbmon.sh => dbmon.sh.in} (81%)
|
||||
mode change 100755 => 100644
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 9aebb6b..4a4b2d3 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -235,7 +235,7 @@ CLEANFILES = dberrstrs.h ns-slapd.properties \
|
||||
ldap/admin/src/scripts/usn-tombstone-cleanup.pl ldap/admin/src/scripts/verify-db.pl \
|
||||
ldap/admin/src/scripts/ds_selinux_port_query ldap/admin/src/scripts/ds_selinux_enabled \
|
||||
ldap/admin/src/scripts/dbverify ldap/admin/src/scripts/readnsstate \
|
||||
- doxyfile.stamp \
|
||||
+ doxyfile.stamp ldap/admin/src/scripts/dbmon.sh \
|
||||
$(NULL)
|
||||
|
||||
clean-local:
|
||||
diff --git a/ldap/admin/src/scripts/dbmon.sh b/ldap/admin/src/scripts/dbmon.sh.in
|
||||
old mode 100755
|
||||
new mode 100644
|
||||
similarity index 81%
|
||||
rename from ldap/admin/src/scripts/dbmon.sh
|
||||
rename to ldap/admin/src/scripts/dbmon.sh.in
|
||||
index 3b8b4d1..4ee6adc
|
||||
--- a/ldap/admin/src/scripts/dbmon.sh
|
||||
+++ b/ldap/admin/src/scripts/dbmon.sh.in
|
||||
@@ -8,10 +8,11 @@
|
||||
# END COPYRIGHT BLOCK
|
||||
#
|
||||
|
||||
+. @datadir@/@package_name@/data/DSSharedLib
|
||||
+
|
||||
DURATION=${DURATION:-0}
|
||||
INCR=${INCR:-1}
|
||||
-HOST=${HOST:-localhost}
|
||||
-PORT=${PORT:-389}
|
||||
+SERVID=${SERVID}
|
||||
BINDDN=${BINDDN:-"cn=directory manager"}
|
||||
BINDPW=${BINDPW:-"secret"}
|
||||
DBLIST=${DBLIST:-all}
|
||||
@@ -180,10 +181,63 @@ parseldif() {
|
||||
}
|
||||
|
||||
dodbmon() {
|
||||
+ initfile=$(get_init_file "@initconfigdir@" $SERVID)
|
||||
+ if [ $? -eq 1 ]
|
||||
+ then
|
||||
+ echo "You must supply a valid server instance identifier (via SERVID)."
|
||||
+ echo "Available instances: $initfile"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+
|
||||
+ . $initfile
|
||||
+
|
||||
+ process_dse $CONFIG_DIR $$
|
||||
+ file="/tmp/DSSharedLib.$$"
|
||||
+ port=$(grep -i 'nsslapd-port' $file | awk '{print $2}' )
|
||||
+ host=$(grep -i 'nsslapd-localhost' $file | awk '{print $2}' )
|
||||
+ security=$(grep -i 'nsslapd-security' $file | awk '{print $2}' )
|
||||
+ certdir=$(grep -i 'nsslapd-certdir' $file | awk '{print $2}' )
|
||||
+ rm $file
|
||||
+
|
||||
+ if [ -n "$ldapiURL" ]
|
||||
+ then
|
||||
+ ldapiURL=`echo "$ldapiURL" | sed -e 's/\//%2f/g'`
|
||||
+ ldapiURL="ldapi://"$ldapiURL
|
||||
+ fi
|
||||
+
|
||||
+ client_type=`ldapsearch -V 2>&1`;
|
||||
+ echo "$client_type" | grep -q "OpenLDAP"
|
||||
+ if [ $? -eq 0 ]
|
||||
+ then
|
||||
+ openldap="yes"
|
||||
+ export LDAPTLS_CACERTDIR=$certdir
|
||||
+ fi
|
||||
+
|
||||
+ if [ -z $security ]; then
|
||||
+ security="off"
|
||||
+ fi
|
||||
+
|
||||
while [ 1 ] ; do
|
||||
date
|
||||
- ldapsearch -xLLL -h $HOST -p $PORT -D "$BINDDN" -w "$BINDPW" -b "$ldbmdn" '(|(cn=config)(cn=database)(cn=monitor))' \
|
||||
- | parseldif
|
||||
+ if [ "$security" = "on" ]; then
|
||||
+ # STARTTLS
|
||||
+ if [ "$openldap" = "yes" ]; then
|
||||
+ ldapsearch -x -LLL -ZZ -h $host -p $port -D "$BINDDN" -w "$BINDPW" -b "$ldbmdn" '(|(cn=config)(cn=database)(cn=monitor))' \
|
||||
+ | parseldif
|
||||
+ else
|
||||
+ ldapsearch -ZZZ -P $certdir -h $host -p $port -D "$BINDDN" -w "$BINDPW" -b "$ldbmdn" '(|(cn=config)(cn=database)(cn=monitor))' \
|
||||
+ | parseldif
|
||||
+ fi
|
||||
+ else
|
||||
+ # LDAP
|
||||
+ if [ "$openldap" = "yes" ]; then
|
||||
+ ldapsearch -x -LLL -h $host -p $port -D "$BINDDN" -w "$BINDPW" -b "$ldbmdn" '(|(cn=config)(cn=database)(cn=monitor))' \
|
||||
+ | parseldif
|
||||
+ else
|
||||
+ ldapsearch -h $host -p $port -D "$BINDDN" -w "$BINDPW" -b "$ldbmdn" '(|(cn=config)(cn=database)(cn=monitor))' \
|
||||
+ | parseldif
|
||||
+ fi
|
||||
+ fi
|
||||
echo ""
|
||||
sleep $INCR
|
||||
done
|
||||
diff --git a/man/man8/dbmon.sh.8 b/man/man8/dbmon.sh.8
|
||||
index 49e61d0..ad318a1 100644
|
||||
--- a/man/man8/dbmon.sh.8
|
||||
+++ b/man/man8/dbmon.sh.8
|
||||
@@ -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 DBMON.SH 8 "Jul 25, 2014"
|
||||
+.TH DBMON.SH 8 "Mar 20, 2017"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@@ -18,7 +18,7 @@
|
||||
.SH NAME
|
||||
dbmon.sh - Directory Server script for monitoring database and entry cache usage
|
||||
.SH SYNOPSIS
|
||||
-[INCR=num] [HOST=hostname] [PORT=num] [BINDDN=binddn] [BINDPW=password] [DBLIST=databases] [INDEXLIST=indexes] [VERBOSE=num] dbmon.sh
|
||||
+[INCR=num] [SERVID=server_id][BINDDN=binddn] [BINDPW=password] [DBLIST=databases] [INDEXLIST=indexes] [VERBOSE=num] dbmon.sh
|
||||
.SH DESCRIPTION
|
||||
dbmon.sh is a tool used to monitor database and entry cache usage. It is especially useful for database cache and entry/dn cache tuning - how much space is left, is the cache full, how much space on average do I need per entry/dn.
|
||||
.SH OPTIONS
|
||||
@@ -31,9 +31,7 @@ All arguments are optional, but you will most likely have to provide BINDPW
|
||||
.TP
|
||||
.B \fBINCR\fR - show results every INCR seconds - default is 1 second
|
||||
.TP
|
||||
-.B \fBHOST\fR - name of host or IP address - default is "localhost"
|
||||
-.TP
|
||||
-.B \fBPORT\fR - port number (LDAP not LDAPS) - default is 389
|
||||
+.B \fBSERVID\fR - Name of the server instance
|
||||
.TP
|
||||
.B \fBBINDDN\fR - DN to use to bind - must have permission to read everything under cn=config - default is cn=Directory Manager
|
||||
.TP
|
||||
@@ -46,11 +44,11 @@ All arguments are optional, but you will most likely have to provide BINDPW
|
||||
.B \fBVERBOSE\fR - output level - 0 == suitable for parsing by a script - 1 == has column headings - 2 == provides detailed descriptions of the data - default is 0
|
||||
|
||||
.SH EXAMPLE
|
||||
-INCR=1 HOST=ldap.example.com BINDDN="cn=directory manager" BINDPW="secret" VERBOSE=2 dbmon.sh
|
||||
+INCR=1 SERVID=slapd-localhost BINDDN="cn=directory manager" BINDPW="secret" VERBOSE=2 dbmon.sh
|
||||
|
||||
.SH AUTHOR
|
||||
dbmon.sh was written by the 389 Project.
|
||||
.SH "REPORTING BUGS"
|
||||
-Report bugs to https://fedorahosted.org/389/newticket.
|
||||
+Report bugs to https://pagure.io/389-ds-base/new_issue
|
||||
.SH COPYRIGHT
|
||||
-Copyright \(co 2014 Red Hat, Inc.
|
||||
+Copyright \(co 2017 Red Hat, Inc.
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
From abc9ff876209819c8f0dd7e799f1ab6a1b084fe5 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 20 Mar 2017 15:08:45 -0400
|
||||
Subject: [PATCH] Issue 49095 - targetattr wildcard evaluation is incorrectly
|
||||
case sensitive
|
||||
|
||||
Description: When processing an aci that uses a wildcard targetattr, the
|
||||
comparision should be done using case insensitive functions.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49095
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49095_test.py | 85 +++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/acl/acl.c | 10 ++--
|
||||
2 files changed, 90 insertions(+), 5 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49095_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49095_test.py b/dirsrvtests/tests/tickets/ticket49095_test.py
|
||||
new file mode 100644
|
||||
index 0000000..04f92b2
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49095_test.py
|
||||
@@ -0,0 +1,85 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import DirSrv, Entry, tools, tasks
|
||||
+from lib389.tools import DirSrvTools
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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=testuser,dc=example,dc=com'
|
||||
+acis = ['(targetattr != "tele*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
||||
+ '(targetattr != "TELE*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
||||
+ '(targetattr != "telephonenum*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
||||
+ '(targetattr != "TELEPHONENUM*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)']
|
||||
+
|
||||
+
|
||||
+def test_ticket49095(topo):
|
||||
+ """Check that target attrbiutes with wildcards are case insensitive
|
||||
+ """
|
||||
+
|
||||
+ # Add an entry
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((USER_DN, {
|
||||
+ 'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'uid': 'testuser',
|
||||
+ 'telephonenumber': '555-555-5555'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add test user: ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ for aci in acis:
|
||||
+ # Add ACI
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(DEFAULT_SUFFIX,
|
||||
+ [(ldap.MOD_REPLACE, 'aci', aci)])
|
||||
+
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to set aci: ' + aci + ': ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Set Anonymous Bind to test aci
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s("", "")
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind anonymously: ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Search for entry - should not get any results
|
||||
+ try:
|
||||
+ entry = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE,
|
||||
+ 'telephonenumber=*')
|
||||
+ if entry:
|
||||
+ log.fatal('The entry was incorrectly returned')
|
||||
+ assert False
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to search anonymously: ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Set root DN Bind so we can update aci's
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind anonymously: ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ log.info("Test Passed")
|
||||
+
|
||||
+
|
||||
+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/acl/acl.c b/ldap/servers/plugins/acl/acl.c
|
||||
index 0a93808..48b8efc 100644
|
||||
--- a/ldap/servers/plugins/acl/acl.c
|
||||
+++ b/ldap/servers/plugins/acl/acl.c
|
||||
@@ -3407,19 +3407,19 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
||||
}
|
||||
|
||||
/* this assumes that str and the filter components are already
|
||||
- * normalized. If not, it shoul be done
|
||||
+ * normalized. If not, it should be done
|
||||
*/
|
||||
if ( initial != NULL) {
|
||||
len = strlen(initial);
|
||||
if (exact_match) {
|
||||
- int rc = strncmp(p, initial, len);
|
||||
+ int rc = strncasecmp(p, initial, len);
|
||||
if (rc) {
|
||||
return ACL_FALSE;
|
||||
} else {
|
||||
p += len;
|
||||
}
|
||||
} else {
|
||||
- p = strstr(p, initial);
|
||||
+ p = strcasestr(p, initial);
|
||||
if (p) {
|
||||
p += len;
|
||||
} else {
|
||||
@@ -3430,7 +3430,7 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
||||
|
||||
if ( any != NULL) {
|
||||
for (i = 0; any && any[i] != NULL; i++) {
|
||||
- p = strstr(p, any[i]);
|
||||
+ p = strcasestr(p, any[i]);
|
||||
if (p) {
|
||||
p += strlen(any[i]);
|
||||
} else {
|
||||
@@ -3444,7 +3444,7 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
||||
len = strlen(final);
|
||||
tlen = strlen(p);
|
||||
if (len > tlen) return ACL_FALSE;
|
||||
- if (strcmp(p+tlen-len, final)) return ACL_FALSE;
|
||||
+ if (strcasecmp(p+tlen-len, final)) return ACL_FALSE;
|
||||
}
|
||||
|
||||
return ACL_TRUE;
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
From e33f58d5a9984fd5d5533425fb420d05e6484d7f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 20 Mar 2017 15:29:48 -0400
|
||||
Subject: [PATCH] Issue 49157 - ds-logpipe.py crashes for non-existing users
|
||||
|
||||
Description: Added try/except's for various OS function calls, as the tool
|
||||
should gracefully exit when there is a problem and not crash
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49157
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-logpipe.py | 25 ++++++++++++++++++-------
|
||||
1 file changed, 18 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-logpipe.py b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
index 4ba4d1b..dc1856a 100644
|
||||
--- a/ldap/admin/src/scripts/ds-logpipe.py
|
||||
+++ b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
@@ -262,7 +262,8 @@ def parse_options():
|
||||
|
||||
options, logfname = parse_options()
|
||||
|
||||
-if options.debug: debug = True
|
||||
+if options.debug:
|
||||
+ debug = True
|
||||
|
||||
if len(plgfuncs) == 0:
|
||||
plgfuncs.append(defaultplugin)
|
||||
@@ -270,9 +271,15 @@ if len(plgpostfuncs) == 0:
|
||||
plgpostfuncs.append(defaultpost)
|
||||
|
||||
if options.user:
|
||||
- try: userid = int(options.user)
|
||||
- except ValueError: # not a numeric userid - look it up
|
||||
- userid = pwd.getpwnam(options.user)[2]
|
||||
+ try:
|
||||
+ userid = int(options.user)
|
||||
+ except ValueError: # not a numeric userid - look it up
|
||||
+ try:
|
||||
+ userid = pwd.getpwnam(options.user)[2]
|
||||
+ except Exception as e:
|
||||
+ print("Failed to lookup name (%s) error: %s" %
|
||||
+ (options.user, str(e)))
|
||||
+ sys.exit(1)
|
||||
os.seteuid(userid)
|
||||
|
||||
if options.scriptpidfile:
|
||||
@@ -298,8 +305,12 @@ except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
if debug:
|
||||
print("Creating log pipe", logfname)
|
||||
- os.mkfifo(logfname)
|
||||
- os.chmod(logfname, 0o600)
|
||||
+ try:
|
||||
+ os.mkfifo(logfname)
|
||||
+ os.chmod(logfname, 0o600)
|
||||
+ except Exception as e:
|
||||
+ print("Failed to create log pipe: " + str(e))
|
||||
+ sys.exit(1)
|
||||
else:
|
||||
raise Exception("%s [%d]" % (e.strerror, e.errno))
|
||||
|
||||
@@ -393,7 +404,7 @@ while not done:
|
||||
else: # we read something
|
||||
# pipe closed - usually when server shuts down
|
||||
done = True
|
||||
-
|
||||
+
|
||||
if not done and debug:
|
||||
print("log pipe", logfname, "closed - reopening - read", totallines, "total lines")
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
From 8c39c9dbe69949065940019e930c37b8f5450a75 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Tkac <vonsch@gmail.com>
|
||||
Date: Sat, 18 Mar 2017 23:34:54 +0100
|
||||
Subject: [PATCH] Fix double-free in _cl5NewDBFile() error path
|
||||
|
||||
Although slapi_ch_free should prevent double-free errors, it doesn't work
|
||||
in old code because after assignment
|
||||
|
||||
(*dbFile)->name = name;
|
||||
|
||||
two independent pointers points to the same allocated area and both pointers
|
||||
are free()-ed (one directly in error path in _cl5NewDBFile and the second
|
||||
in _cl5DBCloseFile, called in error path as well).
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index fc70ab7..5c2233f 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -6269,9 +6269,10 @@ out:
|
||||
}
|
||||
|
||||
(*dbFile)->db = db;
|
||||
- (*dbFile)->name = name;
|
||||
- (*dbFile)->replName = slapi_ch_strdup (replName);
|
||||
- (*dbFile)->replGen = slapi_ch_strdup (replGen);
|
||||
+ (*dbFile)->name = name;
|
||||
+ name = NULL; /* transfer ownership to dbFile struct */
|
||||
+ (*dbFile)->replName = slapi_ch_strdup (replName);
|
||||
+ (*dbFile)->replGen = slapi_ch_strdup (replGen);
|
||||
|
||||
/*
|
||||
* Considerations for setting up cl semaphore:
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
From 8f908a1de1906a0b7451505d9640e2fd2f9fa7eb Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 10:18:13 -0400
|
||||
Subject: [PATCH] Issue 49188 - retrocl can crash server at shutdown
|
||||
|
||||
Description: We do not calloc enough elements when processing nsslapd-attribute
|
||||
from the retrocl plugin configuration. This causes invalid memory
|
||||
to be freed at shutdown(via slapi_ch_array_free).
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49188
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
---
|
||||
ldap/servers/plugins/retrocl/retrocl.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
|
||||
index 32b30c7..6e68667 100644
|
||||
--- a/ldap/servers/plugins/retrocl/retrocl.c
|
||||
+++ b/ldap/servers/plugins/retrocl/retrocl.c
|
||||
@@ -470,8 +470,8 @@ static int retrocl_start (Slapi_PBlock *pb)
|
||||
|
||||
retrocl_nattributes = n;
|
||||
|
||||
- retrocl_attributes = (char **)slapi_ch_calloc(n, sizeof(char *));
|
||||
- retrocl_aliases = (char **)slapi_ch_calloc(n, sizeof(char *));
|
||||
+ retrocl_attributes = (char **)slapi_ch_calloc(n + 1, sizeof(char *));
|
||||
+ retrocl_aliases = (char **)slapi_ch_calloc(n + 1, sizeof(char *));
|
||||
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_start - Attributes:\n");
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
From fffbb3d39a2ea12a2b3a72c729e76c1e69a19d8f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 27 Mar 2017 14:33:17 -0400
|
||||
Subject: [PATCH] Ticket 49177 - rpm would not create valid pkgconfig files
|
||||
|
||||
Bug Description: pkgconfig from the rpm was not valid.
|
||||
|
||||
Fix Description: Resolve an issue in the way we handle the file
|
||||
substiution to resolve this issue.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49177
|
||||
---
|
||||
Makefile.am | 10 ++--------
|
||||
configure.ac | 3 +++
|
||||
m4/mozldap.m4 | 4 ++++
|
||||
m4/openldap.m4 | 4 ++++
|
||||
src/pkgconfig/dirsrv.pc.in | 4 ++++
|
||||
5 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 4a4b2d3..982dd28 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -110,14 +110,12 @@ if OPENLDAP
|
||||
# shared lib _fini for one will stomp on the other, and the program will crash
|
||||
LDAPSDK_LINK_NOTHR = @openldap_lib@ -lldap@ol_libver@ @ldap_lib_ldif@ -llber@ol_libver@
|
||||
LDAPSDK_LINK = @openldap_lib@ -lldap_r@ol_libver@ @ldap_lib_ldif@ -llber@ol_libver@
|
||||
-ldaplib = openldap
|
||||
-ldaplib_defs = -DUSE_OPENLDAP
|
||||
else
|
||||
LDAPSDK_LINK = @ldapsdk_lib@ -lssldap60 -lprldap60 -lldap60 -lldif60
|
||||
LDAPSDK_LINK_NOTHR = $(LDAPSDK_LINK)
|
||||
-ldaplib = mozldap
|
||||
-ldaplib_defs =
|
||||
endif
|
||||
+ldaplib = @ldaplib@
|
||||
+ldaplib_defs = @ldaplib_defs@
|
||||
|
||||
DB_LINK = @db_lib@ -ldb-@db_libver@
|
||||
SASL_LINK = @sasl_lib@ -lsasl2
|
||||
@@ -2237,10 +2235,6 @@ else
|
||||
$(fixupcmd) $^ | sed -n -e 's/@preamble@//' -e '/^#/{p;d;}' -e '/^$$/{p;d;}' -e 's/^\([^=]*\)\(=.*\)$$/\1\2 ; export \1/ ; p' > $@
|
||||
endif
|
||||
|
||||
-%/$(PACKAGE_NAME).pc: %/dirsrv.pc.in
|
||||
- if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi
|
||||
- $(fixupcmd) $^ > $@
|
||||
-
|
||||
%/$(PACKAGE_NAME)-snmp: %/ldap-agent-initscript.in
|
||||
if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi
|
||||
$(fixupcmd) $^ > $@
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 4e3e9fb..3f2aa75 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -785,6 +785,8 @@ AC_SUBST(openldap_inc)
|
||||
AC_SUBST(openldap_lib)
|
||||
AC_SUBST(openldap_libdir)
|
||||
AC_SUBST(openldap_bindir)
|
||||
+AC_SUBST(ldaplib)
|
||||
+AC_SUBST(ldaplib_defs)
|
||||
AC_SUBST(ldaptool_bindir)
|
||||
AC_SUBST(ldaptool_opts)
|
||||
AC_SUBST(plainldif_opts)
|
||||
@@ -853,6 +855,7 @@ if test "$GCC" != yes ; then
|
||||
fi
|
||||
|
||||
# Build our pkgconfig files
|
||||
+# This currently conflicts with %.in: rule in Makefile.am, which should be removed eventually.
|
||||
AC_CONFIG_FILES([src/pkgconfig/dirsrv.pc src/pkgconfig/nunc-stans.pc src/pkgconfig/libsds.pc])
|
||||
|
||||
AC_CONFIG_FILES([Makefile rpm/389-ds-base.spec ])
|
||||
diff --git a/m4/mozldap.m4 b/m4/mozldap.m4
|
||||
index 4352151..8084ed8 100644
|
||||
--- a/m4/mozldap.m4
|
||||
+++ b/m4/mozldap.m4
|
||||
@@ -15,6 +15,8 @@ AC_ARG_WITH(ldapsdk, AS_HELP_STRING([--with-ldapsdk@<:@=PATH@:>@],[Mozilla LDAP
|
||||
if test "$withval" = yes
|
||||
then
|
||||
AC_MSG_RESULT(yes)
|
||||
+ ldaplib="mozldap"
|
||||
+ ldaplib_defs=""
|
||||
elif test "$withval" = no
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -22,6 +24,8 @@ AC_ARG_WITH(ldapsdk, AS_HELP_STRING([--with-ldapsdk@<:@=PATH@:>@],[Mozilla LDAP
|
||||
then
|
||||
AC_MSG_RESULT([using $withval])
|
||||
LDAPSDKDIR=$withval
|
||||
+ ldaplib="mozldap"
|
||||
+ ldaplib_defs=""
|
||||
ldapsdk_inc="-I$LDAPSDKDIR/include"
|
||||
ldapsdk_lib="-L$LDAPSDKDIR/lib"
|
||||
ldapsdk_libdir="$LDAPSDKDIR/lib"
|
||||
diff --git a/m4/openldap.m4 b/m4/openldap.m4
|
||||
index 417bf43..f45637c 100644
|
||||
--- a/m4/openldap.m4
|
||||
+++ b/m4/openldap.m4
|
||||
@@ -15,6 +15,8 @@ AC_ARG_WITH(openldap, AS_HELP_STRING([--with-openldap@<:@=PATH@:>@],[Use OpenLDA
|
||||
if test "$withval" = yes
|
||||
then
|
||||
AC_MSG_RESULT([using system OpenLDAP])
|
||||
+ ldaplib="openldap"
|
||||
+ ldaplib_defs="-DUSE_OPENLDAP"
|
||||
elif test "$withval" = no
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -22,6 +24,8 @@ AC_ARG_WITH(openldap, AS_HELP_STRING([--with-openldap@<:@=PATH@:>@],[Use OpenLDA
|
||||
then
|
||||
AC_MSG_RESULT([using $withval])
|
||||
OPENLDAPDIR=$withval
|
||||
+ ldaplib="openldap"
|
||||
+ ldaplib_defs="-DUSE_OPENLDAP"
|
||||
openldap_incdir="$OPENLDAPDIR/include"
|
||||
openldap_inc="-I$openldap_incdir"
|
||||
openldap_lib="-L$OPENLDAPDIR/lib"
|
||||
diff --git a/src/pkgconfig/dirsrv.pc.in b/src/pkgconfig/dirsrv.pc.in
|
||||
index 4140031..df433cf 100644
|
||||
--- a/src/pkgconfig/dirsrv.pc.in
|
||||
+++ b/src/pkgconfig/dirsrv.pc.in
|
||||
@@ -1,3 +1,7 @@
|
||||
+prefix=@prefix@
|
||||
+exec_prefix=@exec_prefix@
|
||||
+libdir=@libdir@
|
||||
+includedir=@includedir@
|
||||
ldaplib=@ldaplib@
|
||||
|
||||
Name: dirsrv
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
From 1a66f5f232d6c2869ef4e439eafe5a820f61a976 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 11:31:27 +0100
|
||||
Subject: [PATCH] Ticket 49076 - To debug DB_DEADLOCK condition, allow to reset
|
||||
DB_TXN_NOWAIT flag on txn_begin
|
||||
|
||||
Bug Description:
|
||||
For debug reason it is interesting to have a new configuration ldbm backend config
|
||||
option (nsslapd-db-transaction-wait) that allows to hang on deadlock
|
||||
rather to let the server handling retries.
|
||||
|
||||
Fix Description:
|
||||
The fix introduce a new attribute nsslapd-db-transaction-wait under
|
||||
"cn=config,cn=ldbm database,cn=plugins,cn=config".
|
||||
By default it is "off" (ldbm returns DB_DEADLOCK) and can be changed
|
||||
online.
|
||||
It is taken into account when a new transcation begin.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49076
|
||||
|
||||
Reviewed by: William Brown, Ludwig Krispenz
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49076_test.py | 103 ++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/back-ldbm/dblayer.c | 9 ++-
|
||||
ldap/servers/slapd/back-ldbm/dblayer.h | 3 +
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 22 ++++++
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.h | 1 +
|
||||
5 files changed, 137 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49076_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49076_test.py b/dirsrvtests/tests/tickets/ticket49076_test.py
|
||||
new file mode 100644
|
||||
index 0000000..c4a2c1b
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49076_test.py
|
||||
@@ -0,0 +1,103 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import DirSrv, Entry, tools, tasks
|
||||
+from lib389.tools import DirSrvTools
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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__)
|
||||
+
|
||||
+ldbm_config = "cn=config,%s" % (DN_LDBM)
|
||||
+txn_begin_flag = "nsslapd-db-transaction-wait"
|
||||
+TEST_USER_DN = 'cn=test,%s' % SUFFIX
|
||||
+TEST_USER = "test"
|
||||
+
|
||||
+def _check_configured_value(topology_st, attr=txn_begin_flag, expected_value=None, required=False):
|
||||
+ entries = topology_st.standalone.search_s(ldbm_config, ldap.SCOPE_BASE, 'cn=config')
|
||||
+ if required:
|
||||
+ assert (entries[0].hasValue(attr))
|
||||
+ if entries[0].hasValue(attr):
|
||||
+ topology_st.standalone.log.info('Current value is %s' % entries[0].getValue(attr))
|
||||
+ assert (entries[0].getValue(attr) == expected_value)
|
||||
+
|
||||
+def _update_db(topology_st):
|
||||
+ topology_st.standalone.add_s(
|
||||
+ Entry((TEST_USER_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
|
||||
+ 'cn': TEST_USER,
|
||||
+ 'sn': TEST_USER,
|
||||
+ 'givenname': TEST_USER})))
|
||||
+ topology_st.standalone.delete_s(TEST_USER_DN)
|
||||
+
|
||||
+def test_ticket49076(topo):
|
||||
+ """Write your testcase here...
|
||||
+
|
||||
+ Also, if you need any testcase initialization,
|
||||
+ please, write additional fixture for that(include finalizer).
|
||||
+ """
|
||||
+
|
||||
+ # check default value is DB_TXN_NOWAIT
|
||||
+ _check_configured_value(topo, expected_value="off")
|
||||
+
|
||||
+ # tests we are able to update DB
|
||||
+ _update_db(topo)
|
||||
+
|
||||
+ # switch to wait mode
|
||||
+ topo.standalone.modify_s(ldbm_config,
|
||||
+ [(ldap.MOD_REPLACE, txn_begin_flag, "on")])
|
||||
+ # check default value is DB_TXN_NOWAIT
|
||||
+ _check_configured_value(topo, expected_value="on")
|
||||
+ _update_db(topo)
|
||||
+
|
||||
+
|
||||
+ # switch back to "normal mode"
|
||||
+ topo.standalone.modify_s(ldbm_config,
|
||||
+ [(ldap.MOD_REPLACE, txn_begin_flag, "off")])
|
||||
+ # check default value is DB_TXN_NOWAIT
|
||||
+ _check_configured_value(topo, expected_value="off")
|
||||
+ # tests we are able to update DB
|
||||
+ _update_db(topo)
|
||||
+
|
||||
+ # check that settings are not reset by restart
|
||||
+ topo.standalone.modify_s(ldbm_config,
|
||||
+ [(ldap.MOD_REPLACE, txn_begin_flag, "on")])
|
||||
+ # check default value is DB_TXN_NOWAIT
|
||||
+ _check_configured_value(topo, expected_value="on")
|
||||
+ _update_db(topo)
|
||||
+ topo.standalone.restart(timeout=10)
|
||||
+ _check_configured_value(topo, expected_value="on")
|
||||
+ _update_db(topo)
|
||||
+
|
||||
+ # switch default value
|
||||
+ topo.standalone.modify_s(ldbm_config,
|
||||
+ [(ldap.MOD_DELETE, txn_begin_flag, None)])
|
||||
+ # check default value is DB_TXN_NOWAIT
|
||||
+ _check_configured_value(topo, expected_value="off")
|
||||
+ # tests we are able to update DB
|
||||
+ _update_db(topo)
|
||||
+ topo.standalone.restart(timeout=10)
|
||||
+ _check_configured_value(topo, expected_value="off")
|
||||
+ # tests we are able to update DB
|
||||
+ _update_db(topo)
|
||||
+
|
||||
+
|
||||
+ 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/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
index 683994f..507a3cc 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
@@ -3374,6 +3374,8 @@ dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn,
|
||||
|
||||
if (priv->dblayer_enable_transactions)
|
||||
{
|
||||
+ int txn_begin_flags;
|
||||
+
|
||||
dblayer_private_env *pEnv = priv->dblayer_env;
|
||||
if(use_lock) slapi_rwlock_rdlock(pEnv->dblayer_env_lock);
|
||||
if (!parent_txn)
|
||||
@@ -3383,11 +3385,16 @@ dblayer_txn_begin_ext(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn,
|
||||
if (par_txn_txn) {
|
||||
parent_txn = par_txn_txn->back_txn_txn;
|
||||
}
|
||||
+ }
|
||||
+ if (priv->dblayer_txn_wait) {
|
||||
+ txn_begin_flags = 0;
|
||||
+ } else {
|
||||
+ txn_begin_flags = DB_TXN_NOWAIT;
|
||||
}
|
||||
return_value = TXN_BEGIN(pEnv->dblayer_DB_ENV,
|
||||
(DB_TXN*)parent_txn,
|
||||
&new_txn.back_txn_txn,
|
||||
- DB_TXN_NOWAIT);
|
||||
+ txn_begin_flags);
|
||||
if (0 != return_value)
|
||||
{
|
||||
if(use_lock) slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
index e02e6e0..e4307fc 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
@@ -104,6 +104,9 @@ struct dblayer_private
|
||||
* the mpool */
|
||||
int dblayer_recovery_required;
|
||||
int dblayer_enable_transactions;
|
||||
+ int dblayer_txn_wait; /* Default is "off" (DB_TXN_NOWAIT) but for
|
||||
+ * support purpose it could be helpful to set
|
||||
+ * "on" so that backend hang on deadlock */
|
||||
int dblayer_durable_transactions;
|
||||
int dblayer_checkpoint_interval;
|
||||
int dblayer_circular_logging;
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index 8541224..dfe7a13 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -636,6 +636,27 @@ static int ldbm_config_db_transaction_logging_set(void *arg, void *value, char *
|
||||
return retval;
|
||||
}
|
||||
|
||||
+
|
||||
+static void *ldbm_config_db_transaction_wait_get(void *arg)
|
||||
+{
|
||||
+ struct ldbminfo *li = (struct ldbminfo *) arg;
|
||||
+
|
||||
+ return (void *) ((uintptr_t)li->li_dblayer_private->dblayer_txn_wait);
|
||||
+}
|
||||
+
|
||||
+static int ldbm_config_db_transaction_wait_set(void *arg, void *value, char *errorbuf, int phase, int apply)
|
||||
+{
|
||||
+ struct ldbminfo *li = (struct ldbminfo *) arg;
|
||||
+ int retval = LDAP_SUCCESS;
|
||||
+ int val = (int) ((uintptr_t)value);
|
||||
+
|
||||
+ if (apply) {
|
||||
+ li->li_dblayer_private->dblayer_txn_wait = val;
|
||||
+ }
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
static void *ldbm_config_db_logbuf_size_get(void *arg)
|
||||
{
|
||||
struct ldbminfo *li = (struct ldbminfo *) arg;
|
||||
@@ -1517,6 +1538,7 @@ static config_info ldbm_config[] = {
|
||||
{CONFIG_DB_DURABLE_TRANSACTIONS, CONFIG_TYPE_ONOFF, "on", &ldbm_config_db_durable_transactions_get, &ldbm_config_db_durable_transactions_set, CONFIG_FLAG_ALWAYS_SHOW},
|
||||
{CONFIG_DB_CIRCULAR_LOGGING, CONFIG_TYPE_ONOFF, "on", &ldbm_config_db_circular_logging_get, &ldbm_config_db_circular_logging_set, 0},
|
||||
{CONFIG_DB_TRANSACTION_LOGGING, CONFIG_TYPE_ONOFF, "on", &ldbm_config_db_transaction_logging_get, &ldbm_config_db_transaction_logging_set, 0},
|
||||
+ {CONFIG_DB_TRANSACTION_WAIT, CONFIG_TYPE_ONOFF, "off", &ldbm_config_db_transaction_wait_get, &ldbm_config_db_transaction_wait_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_DB_CHECKPOINT_INTERVAL, CONFIG_TYPE_INT, "60", &ldbm_config_db_checkpoint_interval_get, &ldbm_config_db_checkpoint_interval_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_DB_COMPACTDB_INTERVAL, CONFIG_TYPE_INT, "2592000"/*30days*/, &ldbm_config_db_compactdb_interval_get, &ldbm_config_db_compactdb_interval_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_DB_TRANSACTION_BATCH, CONFIG_TYPE_INT, "0", &dblayer_get_batch_transactions, &dblayer_set_batch_transactions, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.h b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
index f481937..ddec3a8 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
@@ -80,6 +80,7 @@ struct config_info {
|
||||
#define CONFIG_DB_DURABLE_TRANSACTIONS "nsslapd-db-durable-transaction"
|
||||
#define CONFIG_DB_CIRCULAR_LOGGING "nsslapd-db-circular-logging"
|
||||
#define CONFIG_DB_TRANSACTION_LOGGING "nsslapd-db-transaction-logging"
|
||||
+#define CONFIG_DB_TRANSACTION_WAIT "nsslapd-db-transaction-wait"
|
||||
#define CONFIG_DB_CHECKPOINT_INTERVAL "nsslapd-db-checkpoint-interval"
|
||||
#define CONFIG_DB_COMPACTDB_INTERVAL "nsslapd-db-compactdb-interval"
|
||||
#define CONFIG_DB_TRANSACTION_BATCH "nsslapd-db-transaction-batch-val"
|
||||
--
|
||||
2.9.3
|
||||
|
244
SOURCES/0014-Issue-49192-Deleting-suffix-can-hang-server.patch
Normal file
244
SOURCES/0014-Issue-49192-Deleting-suffix-can-hang-server.patch
Normal file
|
@ -0,0 +1,244 @@
|
|||
From 353955ba9b4c487e30315d39d1880b6b784817d2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 27 Mar 2017 10:59:40 -0400
|
||||
Subject: [PATCH] Issue 49192 - Deleting suffix can hang server
|
||||
|
||||
Description: If you attempt to bind as an inactive user the backend rwlock
|
||||
is not unlocked. Regression introduced from issue 49051.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49192
|
||||
|
||||
Reviewed by: nhosoi(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49192_test.py | 177 ++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/bind.c | 3 -
|
||||
ldap/servers/slapd/pw_verify.c | 8 +-
|
||||
3 files changed, 179 insertions(+), 9 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49192_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49192_test.py b/dirsrvtests/tests/tickets/ticket49192_test.py
|
||||
new file mode 100644
|
||||
index 0000000..f770ba7
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49192_test.py
|
||||
@@ -0,0 +1,177 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import Entry
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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__)
|
||||
+
|
||||
+INDEX_DN = 'cn=index,cn=Second_Backend,cn=ldbm database,cn=plugins,cn=config'
|
||||
+SUFFIX_DN = 'cn=Second_Backend,cn=ldbm database,cn=plugins,cn=config'
|
||||
+MY_SUFFIX = "o=hang.com"
|
||||
+USER_DN = 'uid=user,' + MY_SUFFIX
|
||||
+
|
||||
+
|
||||
+def test_ticket49192(topo):
|
||||
+ """Trigger deadlock when removing suffix
|
||||
+ """
|
||||
+
|
||||
+ #
|
||||
+ # Create a second suffix/backend
|
||||
+ #
|
||||
+ log.info('Creating second backend...')
|
||||
+ topo.standalone.backends.create(None, properties={
|
||||
+ BACKEND_NAME: "Second_Backend",
|
||||
+ 'suffix': "o=hang.com",
|
||||
+ })
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(("o=hang.com", {
|
||||
+ 'objectclass': 'top organization'.split(),
|
||||
+ 'o': 'hang.com'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to create 2nd suffix: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ #
|
||||
+ # Add roles
|
||||
+ #
|
||||
+ log.info('Adding roles...')
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(('cn=nsManagedDisabledRole,' + MY_SUFFIX, {
|
||||
+ 'objectclass': ['top', 'LdapSubEntry',
|
||||
+ 'nsRoleDefinition',
|
||||
+ 'nsSimpleRoleDefinition',
|
||||
+ 'nsManagedRoleDefinition'],
|
||||
+ 'cn': 'nsManagedDisabledRole'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add managed role: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(('cn=nsDisabledRole,' + MY_SUFFIX, {
|
||||
+ 'objectclass': ['top', 'LdapSubEntry',
|
||||
+ 'nsRoleDefinition',
|
||||
+ 'nsComplexRoleDefinition',
|
||||
+ 'nsNestedRoleDefinition'],
|
||||
+ 'cn': 'nsDisabledRole',
|
||||
+ 'nsRoledn': 'cn=nsManagedDisabledRole,' + MY_SUFFIX})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add nested role: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(('cn=nsAccountInactivationTmp,' + MY_SUFFIX, {
|
||||
+ 'objectclass': ['top', 'nsContainer'],
|
||||
+ 'cn': 'nsAccountInactivationTmp'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add container: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(('cn=\"cn=nsDisabledRole,' + MY_SUFFIX + '\",cn=nsAccountInactivationTmp,' + MY_SUFFIX, {
|
||||
+ 'objectclass': ['top', 'extensibleObject', 'costemplate',
|
||||
+ 'ldapsubentry'],
|
||||
+ 'nsAccountLock': 'true'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add cos1: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry(('cn=nsAccountInactivation_cos,' + MY_SUFFIX, {
|
||||
+ 'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
|
||||
+ 'cosClassicDefinition'],
|
||||
+ 'cn': 'nsAccountInactivation_cos',
|
||||
+ 'cosTemplateDn': 'cn=nsAccountInactivationTmp,' + MY_SUFFIX,
|
||||
+ 'cosSpecifier': 'nsRole',
|
||||
+ 'cosAttribute': 'nsAccountLock operational'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add cos2 : error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ #
|
||||
+ # Add test entry
|
||||
+ #
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((USER_DN, {
|
||||
+ 'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'uid': 'user',
|
||||
+ 'userpassword': 'password',
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add user: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ #
|
||||
+ # Inactivate the user account
|
||||
+ #
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(USER_DN,
|
||||
+ [(ldap.MOD_ADD,
|
||||
+ 'nsRoleDN',
|
||||
+ 'cn=nsManagedDisabledRole,' + MY_SUFFIX)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to disable user: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ # Bind as user (should fail)
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(USER_DN, 'password')
|
||||
+ log.error("Bind incorrectly worked")
|
||||
+ assert False
|
||||
+ except ldap.UNWILLING_TO_PERFORM:
|
||||
+ log.info('Got error 53 as expected')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Bind has unexpected error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Bind as root DN
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('RootDN Bind has unexpected error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ #
|
||||
+ # Delete suffix
|
||||
+ #
|
||||
+ log.info('Delete the suffix and children...')
|
||||
+ try:
|
||||
+ index_entries = topo.standalone.search_s(
|
||||
+ SUFFIX_DN, ldap.SCOPE_SUBTREE, 'objectclass=top')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to search: %s - error %s' % (SUFFIX_DN, str(e)))
|
||||
+
|
||||
+ for entry in reversed(index_entries):
|
||||
+ try:
|
||||
+ log.info("Deleting: " + entry.dn)
|
||||
+ if entry.dn != SUFFIX_DN and entry.dn != INDEX_DN:
|
||||
+ topo.standalone.search_s(entry.dn,
|
||||
+ ldap.SCOPE_ONELEVEL,
|
||||
+ 'objectclass=top')
|
||||
+ topo.standalone.delete_s(entry.dn)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to delete entry: %s - error %s' %
|
||||
+ (entry.dn, str(e)))
|
||||
+ assert False
|
||||
+
|
||||
+ log.info("Test Passed")
|
||||
+
|
||||
+
|
||||
+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/bind.c b/ldap/servers/slapd/bind.c
|
||||
index 5c4fada..f83df7d 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -771,9 +771,6 @@ do_bind( Slapi_PBlock *pb )
|
||||
/* need_new_pw failed; need_new_pw already send_ldap_result in it. */
|
||||
goto free_and_return;
|
||||
}
|
||||
- if (be) {
|
||||
- slapi_be_Unlock(be);
|
||||
- }
|
||||
} else { /* anonymous */
|
||||
/* set bind creds here so anonymous limits are set */
|
||||
bind_credentials_set(pb->pb_conn, authtype, NULL, NULL, NULL, NULL, NULL);
|
||||
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
||||
index a9fd9ec..852b027 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.c
|
||||
+++ b/ldap/servers/slapd/pw_verify.c
|
||||
@@ -50,8 +50,6 @@ pw_verify_root_dn(const char *dn, const Slapi_Value *cred)
|
||||
*
|
||||
* In the future, this will use the credentials and do mfa.
|
||||
*
|
||||
- * If you get SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS you need to unlock
|
||||
- * the backend.
|
||||
* All other results, it's already released.
|
||||
*/
|
||||
int
|
||||
@@ -81,10 +79,8 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
set_db_default_result_handlers(pb);
|
||||
/* now take the dn, and check it */
|
||||
rc = (*be->be_bind)(pb);
|
||||
- /* now attempt the bind. */
|
||||
- if (rc != SLAPI_BIND_SUCCESS && rc != SLAPI_BIND_ANONYMOUS) {
|
||||
- slapi_be_Unlock(be);
|
||||
- }
|
||||
+ slapi_be_Unlock(be);
|
||||
+
|
||||
return rc;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
From 4f90e73538f1faf101733fcd95392bb77ba9467c Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 14:10:11 +1000
|
||||
Subject: [PATCH] Ticket 49174 - nunc-stans can not use negative timeout
|
||||
|
||||
Bug Description: FreeIPA regularly sets up service accounts with
|
||||
an nsIdleTimeout of -1. As a result of an issue with NS and libevent
|
||||
this would cause an instant timeout and disconnect of the service
|
||||
account.
|
||||
|
||||
Fix Description: Correctly check that jobs are registered to NS.
|
||||
Add validation to NS for negative timeouts. During the job registration,
|
||||
we force the timeout to be a valid value.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49174
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds(Thanks!!!)
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
ldap/servers/slapd/daemon.c | 39 ++++++++++++++++++++++++++++-------
|
||||
src/nunc-stans/ns/ns_event_fw_event.c | 8 -------
|
||||
src/nunc-stans/ns/ns_thrpool.c | 16 ++++++++++++++
|
||||
src/nunc-stans/test/test_nuncstans.c | 20 ++++++++++++++++++
|
||||
4 files changed, 68 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||
index e17a858..a4ea4c0 100644
|
||||
--- a/ldap/servers/slapd/daemon.c
|
||||
+++ b/ldap/servers/slapd/daemon.c
|
||||
@@ -1891,15 +1891,32 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
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_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
|
||||
+ PRStatus job_result = ns_add_timeout_job(conn->c_tp, &tv, NS_JOB_TIMER,
|
||||
ns_handle_closure, conn, NULL);
|
||||
- slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "post closure job "
|
||||
- "for conn %" NSPRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd);
|
||||
+#ifdef DEBUG
|
||||
+ PR_ASSERT(job_result == PR_SUCCESS);
|
||||
+#endif
|
||||
+ if (job_result != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ns_connection_post_io_or_closing", "post closure job "
|
||||
+ "for conn %" NSPRIu64 " for fd=%d failed to be added to event queue\n", conn->c_connid, conn->c_sd);
|
||||
+ } else {
|
||||
+ slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "post closure job "
|
||||
+ "for conn %" NSPRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd);
|
||||
+ }
|
||||
|
||||
}
|
||||
} else {
|
||||
/* process event normally - wait for I/O until idletimeout */
|
||||
- tv.tv_sec = conn->c_idletimeout;
|
||||
+ /* With nunc-stans there is a quirk. When we have idleTimeout of -1
|
||||
+ * which is set on some IPA bind dns for infinite, this causes libevent
|
||||
+ * to *instantly* timeout. So if we detect < 0, we set 0 to this timeout, to
|
||||
+ * catch all possible times that an admin could set.
|
||||
+ */
|
||||
+ if (conn->c_idletimeout < 0) {
|
||||
+ tv.tv_sec = 0;
|
||||
+ } else {
|
||||
+ tv.tv_sec = conn->c_idletimeout;
|
||||
+ }
|
||||
tv.tv_usec = 0;
|
||||
#ifdef DEBUG
|
||||
PR_ASSERT(0 == connection_acquire_nolock(conn));
|
||||
@@ -1913,11 +1930,19 @@ ns_connection_post_io_or_closing(Connection *conn)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
- ns_add_io_timeout_job(conn->c_tp, conn->c_prfd, &tv,
|
||||
+ PRStatus 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);
|
||||
- slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
- "conn %" NSPRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd);
|
||||
+#ifdef DEBUG
|
||||
+ PR_ASSERT(job_result == PR_SUCCESS);
|
||||
+#endif
|
||||
+ if (job_result != PR_SUCCESS) {
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
+ "conn %" NSPRIu64 " for fd=%d failed to be added to event queue\n", conn->c_connid, conn->c_sd);
|
||||
+ } else {
|
||||
+ slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "post I/O job for "
|
||||
+ "conn %" NSPRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd);
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
diff --git a/src/nunc-stans/ns/ns_event_fw_event.c b/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
index 3acbaf7..76936de 100644
|
||||
--- a/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
+++ b/src/nunc-stans/ns/ns_event_fw_event.c
|
||||
@@ -48,7 +48,6 @@ typedef struct event ns_event_fw_sig_t;
|
||||
#include "ns_event_fw.h"
|
||||
#include <syslog.h>
|
||||
|
||||
-
|
||||
static void
|
||||
event_logger_cb(int severity, const char *msg)
|
||||
{
|
||||
@@ -248,13 +247,6 @@ ns_event_fw_mod_io(
|
||||
}
|
||||
if (events) {
|
||||
job->ns_event_fw_fd->ev_events = events;
|
||||
-
|
||||
-#ifdef DEBUG_FSM
|
||||
- /* REALLY make sure that we aren't being re-added */
|
||||
- if (event_pending(job->ns_event_fw_fd, events, tv)) {
|
||||
- abort();
|
||||
- }
|
||||
-#endif
|
||||
event_add(job->ns_event_fw_fd, tv);
|
||||
} else {
|
||||
/* setting the job_type to remove IO events will remove it from the event system */
|
||||
diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c
|
||||
index a867b39..9d87384 100644
|
||||
--- a/src/nunc-stans/ns/ns_thrpool.c
|
||||
+++ b/src/nunc-stans/ns/ns_thrpool.c
|
||||
@@ -180,6 +180,14 @@ ns_thrpool_is_event_shutdown(struct ns_thrpool_t *tp)
|
||||
return result;
|
||||
}
|
||||
|
||||
+static int32_t
|
||||
+validate_event_timeout(struct timeval *tv) {
|
||||
+ if (tv->tv_sec < 0 || tv->tv_usec < 0) {
|
||||
+ /* If we get here, you have done something WRONG */
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
static void
|
||||
job_queue_cleanup(void *arg) {
|
||||
@@ -864,6 +872,10 @@ ns_add_timeout_job(ns_thrpool_t *tp, struct timeval *tv, ns_job_type_t job_type,
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
+ if (validate_event_timeout(tv)) {
|
||||
+ return PR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
/* get an event context for a timer job */
|
||||
_job = alloc_timeout_context(tp, tv, job_type, func, data);
|
||||
if (!_job) {
|
||||
@@ -900,6 +912,10 @@ ns_add_io_timeout_job(ns_thrpool_t *tp, PRFileDesc *fd, struct timeval *tv,
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
+ if (validate_event_timeout(tv)) {
|
||||
+ return PR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
/* Don't allow an accept job to be run outside of the event thread.
|
||||
* We do this so a listener job won't shut down while still processing
|
||||
* current connections in other threads.
|
||||
diff --git a/src/nunc-stans/test/test_nuncstans.c b/src/nunc-stans/test/test_nuncstans.c
|
||||
index 8eef9e6..2795302 100644
|
||||
--- a/src/nunc-stans/test/test_nuncstans.c
|
||||
+++ b/src/nunc-stans/test/test_nuncstans.c
|
||||
@@ -385,6 +385,23 @@ ns_job_signal_cb_test(void **state)
|
||||
assert_int_equal(ns_job_done(job), 0);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Test that given a timeout of -1, we fail to create a job.
|
||||
+ */
|
||||
+
|
||||
+static void
|
||||
+ns_job_neg_timeout_test(void **state)
|
||||
+{
|
||||
+ struct ns_thrpool_t *tp = *state;
|
||||
+
|
||||
+ struct timeval tv = { -1, 0 };
|
||||
+
|
||||
+ PR_ASSERT(PR_FAILURE == ns_add_io_timeout_job(tp, 0, &tv, NS_JOB_THREAD, ns_init_do_nothing_cb, NULL, NULL));
|
||||
+
|
||||
+ PR_ASSERT(PR_FAILURE == ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_init_do_nothing_cb, NULL, NULL));
|
||||
+
|
||||
+}
|
||||
+
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
@@ -410,6 +427,9 @@ main(void)
|
||||
cmocka_unit_test_setup_teardown(ns_job_signal_cb_test,
|
||||
ns_test_setup,
|
||||
ns_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(ns_job_neg_timeout_test,
|
||||
+ ns_test_setup,
|
||||
+ ns_test_teardown),
|
||||
};
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
--
|
||||
2.9.3
|
||||
|
1366
SOURCES/0016-Issue-48989-Integer-overflow.patch
Normal file
1366
SOURCES/0016-Issue-48989-Integer-overflow.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,38 @@
|
|||
From c14b2d88497724c4e19e5fae89bb40c95a61e1cb Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 30 Mar 2017 15:26:00 -0400
|
||||
Subject: [PATCH] Issue 49035 - dbmon.sh shows pages-in-use that exceeds the
|
||||
cache size
|
||||
|
||||
Bug Description: dbmon shows negative free cache stats because the pages-in-use exceeds
|
||||
the expected size of the cache. This is because on caches smaller
|
||||
than 500mb, libdb automatically increases the size by ~25%. The tool
|
||||
is only checking the configured db cache size, and in this case its
|
||||
actaully larger than what was conigured in dse.ldif.
|
||||
|
||||
Fix Description: dbmon.sh should use the libdb's "cache size in bytes", instead of
|
||||
nsslapd-dbcachesize - as it could be different.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49035
|
||||
|
||||
Reviewed by: nhosoi & wibrown (Thanks!!)
|
||||
---
|
||||
ldap/admin/src/scripts/dbmon.sh.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/dbmon.sh.in b/ldap/admin/src/scripts/dbmon.sh.in
|
||||
index 4ee6adc..46796e2 100644
|
||||
--- a/ldap/admin/src/scripts/dbmon.sh.in
|
||||
+++ b/ldap/admin/src/scripts/dbmon.sh.in
|
||||
@@ -47,7 +47,7 @@ parseldif() {
|
||||
}
|
||||
/^[^ ]|^$/ {origline = $0; $0 = unwrapline; unwrapline = origline}
|
||||
/^ / {sub(/^ /, ""); unwrapline = unwrapline $0; next}
|
||||
- /^nsslapd-dbcachesize/ { dbcachesize=$2 }
|
||||
+ /^nsslapd-db-cache-size-bytes/ { dbcachesize=$2 }
|
||||
/^nsslapd-db-page-size/ { pagesize=$2 }
|
||||
/^dbcachehitratio/ { dbhitratio=$2 }
|
||||
/^dbcachepagein/ { dbcachepagein=$2 }
|
||||
--
|
||||
2.9.3
|
||||
|
56
SOURCES/0018-Issue-49177-Fix-pkg-config-file.patch
Normal file
56
SOURCES/0018-Issue-49177-Fix-pkg-config-file.patch
Normal file
|
@ -0,0 +1,56 @@
|
|||
From a1c4718d9db069ab088914ec983af8125eba3ac6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 31 Mar 2017 09:34:27 -0400
|
||||
Subject: [PATCH] Issue 49177 - Fix pkg-config file
|
||||
|
||||
Description: Need to remove the slash in front of the package name
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49177
|
||||
|
||||
Reviewed by: lslebodn & wibrown (Thanks!!)
|
||||
---
|
||||
Makefile.am | 4 ++--
|
||||
configure.ac | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 982dd28..485a460 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -261,7 +261,7 @@ sampledatadir = $(datadir)@sampledatadir@
|
||||
systemschemadir = $(datadir)@systemschemadir@
|
||||
propertydir = $(datadir)@propertydir@
|
||||
schemadir = $(sysconfdir)@schemadir@
|
||||
-serverdir = $(libdir)@serverdir@
|
||||
+serverdir = $(libdir)/@serverdir@
|
||||
serverplugindir = $(libdir)@serverplugindir@
|
||||
taskdir = $(datadir)@scripttemplatedir@
|
||||
systemdsystemunitdir = @with_systemdsystemunitdir@
|
||||
@@ -276,7 +276,7 @@ infdir = $(datadir)@infdir@
|
||||
mibdir = $(datadir)@mibdir@
|
||||
updatedir = $(datadir)@updatedir@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
-serverincdir = $(includedir)@serverincdir@
|
||||
+serverincdir = $(includedir)/@serverincdir@
|
||||
|
||||
defaultuser=@defaultuser@
|
||||
defaultgroup=@defaultgroup@
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 8172bab..51c4414 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -361,9 +361,9 @@ else
|
||||
# relative to datadir
|
||||
updatedir=/$PACKAGE_NAME/updates
|
||||
# relative to libdir
|
||||
- serverdir=/$PACKAGE_NAME
|
||||
+ serverdir=$PACKAGE_NAME
|
||||
# relative to includedir
|
||||
- serverincdir=/$PACKAGE_NAME
|
||||
+ serverincdir=$PACKAGE_NAME
|
||||
# relative to libdir
|
||||
serverplugindir=/$PACKAGE_NAME/plugins
|
||||
# relative to datadir
|
||||
--
|
||||
2.9.3
|
||||
|
1438
SOURCES/0019-Issue-49205-Fix-logconv.pl-man-page.patch
Normal file
1438
SOURCES/0019-Issue-49205-Fix-logconv.pl-man-page.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,121 @@
|
|||
From 578d207cd66e97e9ff8211559c62114a961e35a8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 14:21:47 -0400
|
||||
Subject: [PATCH] Issue 49039 - password min age should be ignored if password
|
||||
needs to be reset
|
||||
|
||||
Description: Do not check the password minimum age when changing a password
|
||||
if the password "must" be reset.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49039
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49039_test.py | 79 +++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/modify.c | 4 +-
|
||||
2 files changed, 81 insertions(+), 2 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49039_test.py b/dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
new file mode 100644
|
||||
index 0000000..e6d4c03
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
@@ -0,0 +1,79 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import Entry
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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=user,dc=example,dc=com'
|
||||
+
|
||||
+
|
||||
+def test_ticket49039(topo):
|
||||
+ """Test "password must change" verses "password min age". Min age should not
|
||||
+ block password update if the password was reset.
|
||||
+ """
|
||||
+
|
||||
+ # Configure password policy
|
||||
+ try:
|
||||
+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on'),
|
||||
+ (ldap.MOD_REPLACE, 'passwordMustChange', 'on'),
|
||||
+ (ldap.MOD_REPLACE, 'passwordExp', 'on'),
|
||||
+ (ldap.MOD_REPLACE, 'passwordMaxAge', '86400000'),
|
||||
+ (ldap.MOD_REPLACE, 'passwordMinAge', '8640000'),
|
||||
+ (ldap.MOD_REPLACE, 'passwordChange', 'on')])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to set password policy: ' + str(e))
|
||||
+
|
||||
+ # Add user, bind, and set password
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((USER_DN, {
|
||||
+ 'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'uid': 'user1',
|
||||
+ 'userpassword': PASSWORD
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add user: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Reset password as RootDN
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ # Reset password as user
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(USER_DN, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to change password: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ log.info('Test Passed')
|
||||
+
|
||||
+
|
||||
+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/modify.c b/ldap/servers/slapd/modify.c
|
||||
index 4bef90a..32defae 100644
|
||||
--- a/ldap/servers/slapd/modify.c
|
||||
+++ b/ldap/servers/slapd/modify.c
|
||||
@@ -1326,8 +1326,8 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old
|
||||
|
||||
/* check if password is within password minimum age;
|
||||
error result is sent directly from check_pw_minage */
|
||||
- if ((internal_op || !pb->pb_conn->c_needpw) &&
|
||||
- check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1)
|
||||
+ if (!pb->pb_conn->c_needpw &&
|
||||
+ check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1)
|
||||
{
|
||||
if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS))
|
||||
{
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
From ea60248d99abb8fed9f7a2b1ab7325c5523b8562 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Mon, 3 Apr 2017 09:32:20 +0200
|
||||
Subject: [PATCH] fix for cve 2017-2668 - simple return text if suffix not
|
||||
found
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1436575
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
ldap/servers/slapd/defbackend.c | 75 ++---------------------------------------
|
||||
1 file changed, 2 insertions(+), 73 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c
|
||||
index 6fd74a3..6cd2c04 100644
|
||||
--- a/ldap/servers/slapd/defbackend.c
|
||||
+++ b/ldap/servers/slapd/defbackend.c
|
||||
@@ -166,50 +166,7 @@ defbackend_abandon( Slapi_PBlock *pb )
|
||||
}
|
||||
|
||||
|
||||
-#define DEFBE_NO_SUCH_SUFFIX "No such suffix"
|
||||
-/*
|
||||
- * Generate a "No such suffix" return text
|
||||
- * Example:
|
||||
- * cn=X,dc=bogus,dc=com ==> "No such suffix (dc=bogus,dc=com)"
|
||||
- * if the last rdn starts with "dc=", print all last dc= rdn's.
|
||||
- * cn=X,cn=bogus ==> "No such suffix (cn=bogus)"
|
||||
- * otherwise, print the very last rdn.
|
||||
- * cn=X,z=bogus ==> "No such suffix (x=bogus)"
|
||||
- * it is true even if it is an invalid rdn.
|
||||
- * cn=X,bogus ==> "No such suffix (bogus)"
|
||||
- * another example of invalid rdn.
|
||||
- */
|
||||
-static void
|
||||
-_defbackend_gen_returntext(char *buffer, size_t buflen, char **dns)
|
||||
-{
|
||||
- int dnidx;
|
||||
- int sidx;
|
||||
- struct suffix_repeat {
|
||||
- char *suffix;
|
||||
- int size;
|
||||
- } candidates[] = {
|
||||
- {"dc=", 3}, /* dc could be repeated. otherwise the last rdn is used. */
|
||||
- {NULL, 0}
|
||||
- };
|
||||
- PR_snprintf(buffer, buflen, "%s (", DEFBE_NO_SUCH_SUFFIX);
|
||||
- for (dnidx = 0; dns[dnidx]; dnidx++) ; /* finding the last */
|
||||
- dnidx--; /* last rdn */
|
||||
- for (sidx = 0; candidates[sidx].suffix; sidx++) {
|
||||
- if (!PL_strncasecmp(dns[dnidx], candidates[sidx].suffix, candidates[sidx].size)) {
|
||||
- while (!PL_strncasecmp(dns[--dnidx], candidates[sidx].suffix, candidates[sidx].size)) ;
|
||||
- PL_strcat(buffer, dns[++dnidx]); /* the first "dn=", e.g. */
|
||||
- for (++dnidx; dns[dnidx]; dnidx++) {
|
||||
- PL_strcat(buffer, ",");
|
||||
- PL_strcat(buffer, dns[dnidx]);
|
||||
- }
|
||||
- PL_strcat(buffer, ")");
|
||||
- return; /* finished the task */
|
||||
- }
|
||||
- }
|
||||
- PL_strcat(buffer, dns[dnidx]);
|
||||
- PL_strcat(buffer, ")");
|
||||
- return;
|
||||
-}
|
||||
+#define DEFBE_NO_SUCH_SUFFIX "No suffix for bind dn found"
|
||||
|
||||
static int
|
||||
defbackend_bind( Slapi_PBlock *pb )
|
||||
@@ -231,36 +188,8 @@ defbackend_bind( Slapi_PBlock *pb )
|
||||
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
|
||||
rc = SLAPI_BIND_ANONYMOUS;
|
||||
} else {
|
||||
- Slapi_DN *sdn = NULL;
|
||||
- char *suffix = NULL;
|
||||
- char **dns = NULL;
|
||||
-
|
||||
- if (pb->pb_op) {
|
||||
- sdn = operation_get_target_spec(pb->pb_op);
|
||||
- if (sdn) {
|
||||
- dns = slapi_ldap_explode_dn(slapi_sdn_get_dn(sdn), 0);
|
||||
- if (dns) {
|
||||
- size_t dnlen = slapi_sdn_get_ndn_len(sdn);
|
||||
- size_t len = dnlen + sizeof(DEFBE_NO_SUCH_SUFFIX) + 4;
|
||||
- suffix = slapi_ch_malloc(len);
|
||||
- if (dnlen) {
|
||||
- _defbackend_gen_returntext(suffix, len, dns);
|
||||
- } else {
|
||||
- PR_snprintf(suffix, len, "%s", DEFBE_NO_SUCH_SUFFIX);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- if (suffix) {
|
||||
- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, suffix);
|
||||
- } else {
|
||||
- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, DEFBE_NO_SUCH_SUFFIX);
|
||||
- }
|
||||
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, DEFBE_NO_SUCH_SUFFIX);
|
||||
send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
|
||||
- if (dns) {
|
||||
- slapi_ldap_value_free(dns);
|
||||
- }
|
||||
- slapi_ch_free_string(&suffix);
|
||||
rc = SLAPI_BIND_FAIL;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
63
SOURCES/0022-Issue-47662-CLI-args-get-removed.patch
Normal file
63
SOURCES/0022-Issue-47662-CLI-args-get-removed.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 3937047eee31638df068b3294aa90ef603915676 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 10 Apr 2017 14:55:55 -0400
|
||||
Subject: [PATCH] Issue 47662 - CLI args get removed
|
||||
|
||||
Bug Description. Regression from previous fix. The process to check unknown
|
||||
CLI options blows away the built-in arg list "$@"
|
||||
|
||||
Fix Description: Make a copy of $@, and use it as needed.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/47662
|
||||
|
||||
Reviewed by: nhosoi(Thanks!)
|
||||
---
|
||||
ldap/admin/src/scripts/db2ldif.in | 3 ++-
|
||||
ldap/admin/src/scripts/ldif2db.in | 3 ++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2ldif.in b/ldap/admin/src/scripts/db2ldif.in
|
||||
index 85854b3..08f30e4 100755
|
||||
--- a/ldap/admin/src/scripts/db2ldif.in
|
||||
+++ b/ldap/admin/src/scripts/db2ldif.in
|
||||
@@ -130,6 +130,7 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
+ARGS=$@
|
||||
shift $(($OPTIND - 1))
|
||||
if [ $1 ]
|
||||
then
|
||||
@@ -156,7 +157,7 @@ fi
|
||||
servid=`normalize_server_id $initfile`
|
||||
. $initfile
|
||||
|
||||
-ldif_file=`make_ldiffile $@`
|
||||
+ldif_file=`make_ldiffile $ARGS`
|
||||
rn=$?
|
||||
|
||||
echo "Exported ldif file: $ldif_file"
|
||||
diff --git a/ldap/admin/src/scripts/ldif2db.in b/ldap/admin/src/scripts/ldif2db.in
|
||||
index f968303..20c7d46 100755
|
||||
--- a/ldap/admin/src/scripts/ldif2db.in
|
||||
+++ b/ldap/admin/src/scripts/ldif2db.in
|
||||
@@ -87,6 +87,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+ARGS=$@
|
||||
shift $(($OPTIND - 1))
|
||||
if [ $1 ]
|
||||
then
|
||||
@@ -106,7 +107,7 @@ fi
|
||||
|
||||
. $initfile
|
||||
|
||||
-handleopts $@
|
||||
+handleopts $ARGS
|
||||
quiet=$?
|
||||
if [ $quiet -eq 0 ]; then
|
||||
echo importing data ...
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
From 5854fc41c6620567f0356e382baec4eda1e645b2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 5 Apr 2017 11:05:28 -0400
|
||||
Subject: [PATCH] Issue 49210 - Fix regression when checking is password min
|
||||
age should be checked
|
||||
|
||||
Bug Description: If a plugin makes an internal modification of userpassword
|
||||
the connection structure in the pblock is null, and it was
|
||||
being dereferenced.
|
||||
|
||||
Fix Description: These internal operations do not need to have the password
|
||||
policy checks done. They are intended to be unrestricted.
|
||||
So we only need to check password policy on client connections.
|
||||
The fix frist hecks if the connection structy is present,
|
||||
only then it continues.
|
||||
|
||||
Revised test script to include the tool: ldappasswd
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49210
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49039_test.py | 62 +++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/modify.c | 2 +-
|
||||
2 files changed, 63 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49039_test.py b/dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
index e6d4c03..f0b224c 100644
|
||||
--- a/dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49039_test.py
|
||||
@@ -2,6 +2,7 @@ import time
|
||||
import ldap
|
||||
import logging
|
||||
import pytest
|
||||
+import os
|
||||
from lib389 import Entry
|
||||
from lib389._constants import *
|
||||
from lib389.properties import *
|
||||
@@ -9,6 +10,7 @@ from lib389.tasks import *
|
||||
from lib389.utils import *
|
||||
from lib389.topologies import topology_st as topo
|
||||
|
||||
+
|
||||
DEBUGGING = os.getenv("DEBUGGING", default=False)
|
||||
if DEBUGGING:
|
||||
logging.getLogger(__name__).setLevel(logging.DEBUG)
|
||||
@@ -19,11 +21,39 @@ log = logging.getLogger(__name__)
|
||||
USER_DN = 'uid=user,dc=example,dc=com'
|
||||
|
||||
|
||||
+def ssl_init(topo):
|
||||
+ """ Setup TLS
|
||||
+ """
|
||||
+ topo.standalone.stop()
|
||||
+ # Prepare SSL but don't enable it.
|
||||
+ for f in ('key3.db', 'cert8.db', 'key4.db', 'cert9.db', 'secmod.db', 'pkcs11.txt'):
|
||||
+ try:
|
||||
+ os.remove("%s/%s" % (topo.standalone.confdir, f))
|
||||
+ except:
|
||||
+ pass
|
||||
+ assert(topo.standalone.nss_ssl.reinit() is True)
|
||||
+ assert(topo.standalone.nss_ssl.create_rsa_ca() is True)
|
||||
+ assert(topo.standalone.nss_ssl.create_rsa_key_and_cert() is True)
|
||||
+ # Start again
|
||||
+ topo.standalone.start()
|
||||
+ topo.standalone.rsa.create()
|
||||
+ topo.standalone.config.set('nsslapd-ssl-check-hostname', 'off')
|
||||
+ topo.standalone.config.set('nsslapd-secureport', '%s' %
|
||||
+ SECUREPORT_STANDALONE1)
|
||||
+ topo.standalone.config.set('nsslapd-security', 'on')
|
||||
+ topo.standalone.restart()
|
||||
+
|
||||
+ log.info("SSL setup complete\n")
|
||||
+
|
||||
+
|
||||
def test_ticket49039(topo):
|
||||
"""Test "password must change" verses "password min age". Min age should not
|
||||
block password update if the password was reset.
|
||||
"""
|
||||
|
||||
+ # Setup SSL (for ldappasswd test)
|
||||
+ ssl_init(topo)
|
||||
+
|
||||
# Configure password policy
|
||||
try:
|
||||
topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on'),
|
||||
@@ -68,6 +98,38 @@ def test_ticket49039(topo):
|
||||
log.fatal('Failed to change password: error ' + e.message['desc'])
|
||||
assert False
|
||||
|
||||
+ ###################################
|
||||
+ # Make sure ldappasswd also works
|
||||
+ ###################################
|
||||
+
|
||||
+ # Reset password as RootDN
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind as rootdn: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ # Run ldappasswd as the User.
|
||||
+ cmd = ('LDAPTLS_REQCERT=never LDAPTLS_CACERTDIR=' + topo.standalone.get_cert_dir() +
|
||||
+ ' ldappasswd' + ' -h ' + topo.standalone.host + ' -Z -p 38901 -D ' + USER_DN +
|
||||
+ ' -w password -a password -s password2 ' + USER_DN)
|
||||
+ os.system(cmd)
|
||||
+ time.sleep(1)
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.simple_bind_s(USER_DN, "password2")
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to bind: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
log.info('Test Passed')
|
||||
|
||||
|
||||
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
|
||||
index 32defae..e23fe67 100644
|
||||
--- a/ldap/servers/slapd/modify.c
|
||||
+++ b/ldap/servers/slapd/modify.c
|
||||
@@ -1326,7 +1326,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old
|
||||
|
||||
/* check if password is within password minimum age;
|
||||
error result is sent directly from check_pw_minage */
|
||||
- if (!pb->pb_conn->c_needpw &&
|
||||
+ if (pb->pb_conn && !pb->pb_conn->c_needpw &&
|
||||
check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1)
|
||||
{
|
||||
if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS))
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From 765520fa7bf49f2de542d619b0fce99e13e4d53a Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Tue, 4 Apr 2017 10:44:55 +0200
|
||||
Subject: [PATCH] Ticket 49209 - Hang due to omitted replica lock release
|
||||
|
||||
Bug Description:
|
||||
When an operation is canceled (failure), its csn is aborted
|
||||
and removed from the pending list.
|
||||
If at that time the pending list is empty or the csn is not found
|
||||
in that list, the cancel callback forgots to release the replica lock
|
||||
|
||||
Fix Description:
|
||||
Release replica lock systematically, whether cnsplRemove fails or not
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49209
|
||||
|
||||
Reviewed by: Mark Reynolds (thanks Mark !!)
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index 7beef50..5718a98 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -3662,6 +3662,7 @@ abort_csn_callback(const CSN *csn, void *data)
|
||||
int rc = csnplRemove(r->min_csn_pl, csn);
|
||||
if (rc) {
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "abort_csn_callback - csnplRemove failed");
|
||||
+ replica_unlock(r->repl_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.9.3
|
||||
|
299
SOURCES/0025-Ticket-49184-Overflow-in-memberof.patch
Normal file
299
SOURCES/0025-Ticket-49184-Overflow-in-memberof.patch
Normal file
|
@ -0,0 +1,299 @@
|
|||
From 710b0a6aaf1c648bc8fd33d4ab5bcc859a0ed851 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Thu, 13 Apr 2017 15:21:49 +0200
|
||||
Subject: [PATCH] Ticket 49184 - Overflow in memberof
|
||||
|
||||
Bug Description:
|
||||
The function memberof_call_foreach_dn can be used to retrieve ancestors of a
|
||||
given entry. (ancestors are groups owning directly or indirectly a given entry).
|
||||
|
||||
With the use of group cache in memberof, at the entrance of memberof_call_foreach_dn
|
||||
there is an attempt to get the entry ancestors from the cache.
|
||||
|
||||
Before doing so it needs to test if the cache is safe. In fact in case of
|
||||
circular groups the use of the cache is disabled and lookup in the cache should not
|
||||
happend.
|
||||
|
||||
To know if the cache is safe it needs to access a flag (use_cache) in callback_data.
|
||||
The callback_data structure is opaque at this level. So accessing it
|
||||
while its structure is unknown is dangerous.
|
||||
|
||||
The bug is that we may read an 'int' at an offset that overflow the actual structure.
|
||||
This is just a test and should not trigger a crash.
|
||||
|
||||
Fix Description:
|
||||
Add a flag to call memberof_call_foreach_dn so that, that indicates if
|
||||
it is valid to use the group cache.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49184
|
||||
|
||||
Reviewed by: William Brown and Mark Reynolds (thanks to you !!)
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49184_test.py | 146 ++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/memberof/memberof.c | 38 ++++---
|
||||
2 files changed, 167 insertions(+), 17 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49184_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49184_test.py b/dirsrvtests/tests/tickets/ticket49184_test.py
|
||||
new file mode 100644
|
||||
index 0000000..20edfde
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49184_test.py
|
||||
@@ -0,0 +1,146 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import DirSrv, Entry, tools, tasks
|
||||
+from lib389.tools import DirSrvTools
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+from lib389.topologies import topology_st as topo
|
||||
+
|
||||
+DEBUGGING = os.getenv("DEBUGGING", default=False)
|
||||
+GROUP_DN_1 = ("cn=group1," + DEFAULT_SUFFIX)
|
||||
+GROUP_DN_2 = ("cn=group2," + DEFAULT_SUFFIX)
|
||||
+SUPER_GRP1 = ("cn=super_grp1," + DEFAULT_SUFFIX)
|
||||
+SUPER_GRP2 = ("cn=super_grp2," + DEFAULT_SUFFIX)
|
||||
+SUPER_GRP3 = ("cn=super_grp3," + DEFAULT_SUFFIX)
|
||||
+
|
||||
+if DEBUGGING:
|
||||
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
|
||||
+else:
|
||||
+ logging.getLogger(__name__).setLevel(logging.INFO)
|
||||
+log = logging.getLogger(__name__)
|
||||
+
|
||||
+def _add_group_with_members(topo, group_dn):
|
||||
+ # Create group
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((group_dn,
|
||||
+ {'objectclass': 'top groupofnames extensibleObject'.split(),
|
||||
+ 'cn': 'group'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add group: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Add members to the group - set timeout
|
||||
+ log.info('Adding members to the group...')
|
||||
+ for idx in range(1, 5):
|
||||
+ try:
|
||||
+ MEMBER_VAL = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ topo.standalone.modify_s(group_dn,
|
||||
+ [(ldap.MOD_ADD,
|
||||
+ 'member',
|
||||
+ MEMBER_VAL)])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to update group: member (%s) - error: %s' %
|
||||
+ (MEMBER_VAL, e.message['desc']))
|
||||
+ assert False
|
||||
+
|
||||
+def _check_memberof(topo, member=None, memberof=True, group_dn=None):
|
||||
+ # Check that members have memberof attribute on M1
|
||||
+ for idx in range(1, 5):
|
||||
+ try:
|
||||
+ USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ ent = topo.standalone.getEntry(USER_DN, ldap.SCOPE_BASE, "(objectclass=*)")
|
||||
+ if presence_flag:
|
||||
+ assert ent.hasAttr('memberof') and ent.getValue('memberof') == group_dn
|
||||
+ else:
|
||||
+ assert not ent.hasAttr('memberof')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to retrieve user (%s): error %s' % (USER_DN, e.message['desc']))
|
||||
+ assert False
|
||||
+
|
||||
+def _check_memberof(topo, member=None, memberof=True, group_dn=None):
|
||||
+ ent = topo.standalone.getEntry(member, ldap.SCOPE_BASE, "(objectclass=*)")
|
||||
+ if memberof:
|
||||
+ assert group_dn
|
||||
+ assert ent.hasAttr('memberof') and group_dn in ent.getValues('memberof')
|
||||
+ else:
|
||||
+ if ent.hasAttr('memberof'):
|
||||
+ assert group_dn not in ent.getValues('memberof')
|
||||
+
|
||||
+
|
||||
+def test_ticket49184(topo):
|
||||
+ """Write your testcase here...
|
||||
+
|
||||
+ Also, if you need any testcase initialization,
|
||||
+ please, write additional fixture for that(include finalizer).
|
||||
+ """
|
||||
+
|
||||
+ topo.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
|
||||
+ topo.standalone.restart(timeout=10)
|
||||
+
|
||||
+ #
|
||||
+ # create some users and a group
|
||||
+ #
|
||||
+ log.info('create users and group...')
|
||||
+ for idx in range(1, 5):
|
||||
+ try:
|
||||
+ USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ topo.standalone.add_s(Entry((USER_DN,
|
||||
+ {'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'uid': 'member%d' % (idx)})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to add user (%s): error %s' % (USER_DN, e.message['desc']))
|
||||
+ assert False
|
||||
+
|
||||
+ # add all users in GROUP_DN_1 and checks each users is memberof GROUP_DN_1
|
||||
+ _add_group_with_members(topo, GROUP_DN_1)
|
||||
+ for idx in range(1, 5):
|
||||
+ USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ _check_memberof(topo, member=USER_DN, memberof=True, group_dn=GROUP_DN_1 )
|
||||
+
|
||||
+ # add all users in GROUP_DN_2 and checks each users is memberof GROUP_DN_2
|
||||
+ _add_group_with_members(topo, GROUP_DN_2)
|
||||
+ for idx in range(1, 5):
|
||||
+ USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ _check_memberof(topo, member=USER_DN, memberof=True, group_dn=GROUP_DN_2 )
|
||||
+
|
||||
+ # add the level 2, 3 and 4 group
|
||||
+ for super_grp in (SUPER_GRP1, SUPER_GRP2, SUPER_GRP3):
|
||||
+ topo.standalone.add_s(Entry((super_grp,
|
||||
+ {'objectclass': 'top groupofnames extensibleObject'.split(),
|
||||
+ 'cn': 'super_grp'})))
|
||||
+ topo.standalone.modify_s(SUPER_GRP1,
|
||||
+ [(ldap.MOD_ADD,
|
||||
+ 'member',
|
||||
+ GROUP_DN_1),
|
||||
+ (ldap.MOD_ADD,
|
||||
+ 'member',
|
||||
+ GROUP_DN_2)])
|
||||
+ topo.standalone.modify_s(SUPER_GRP2,
|
||||
+ [(ldap.MOD_ADD,
|
||||
+ 'member',
|
||||
+ GROUP_DN_1),
|
||||
+ (ldap.MOD_ADD,
|
||||
+ 'member',
|
||||
+ GROUP_DN_2)])
|
||||
+ return
|
||||
+ topo.standalone.delete_s(GROUP_DN_2)
|
||||
+ for idx in range(1, 5):
|
||||
+ USER_DN = ("uid=member%d,%s" % (idx, DEFAULT_SUFFIX))
|
||||
+ _check_memberof(topo, member=USER_DN, memberof=True, group_dn=GROUP_DN_1 )
|
||||
+ _check_memberof(topo, member=USER_DN, memberof=False, group_dn=GROUP_DN_2 )
|
||||
+
|
||||
+ 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 81ef092..5cd2c01 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -159,7 +159,7 @@ static int memberof_qsort_compare(const void *a, const void *b);
|
||||
static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr);
|
||||
static int memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *sdn);
|
||||
static int memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn, MemberOfConfig *config,
|
||||
- char **types, plugin_search_entry_callback callback, void *callback_data, int *cached);
|
||||
+ char **types, plugin_search_entry_callback callback, void *callback_data, int *cached, PRBool use_grp_cache);
|
||||
static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
|
||||
Slapi_Value *memberdn);
|
||||
static int memberof_is_grouping_attr(char *type, MemberOfConfig *config);
|
||||
@@ -659,7 +659,7 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, Slapi_DN *
|
||||
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_del_dn_from_groups: Ancestors of %s\n", slapi_sdn_get_dn(sdn));
|
||||
rc = memberof_call_foreach_dn(pb, sdn, config, groupattrs,
|
||||
- memberof_del_dn_type_callback, &data, &cached);
|
||||
+ memberof_del_dn_type_callback, &data, &cached, PR_FALSE);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -776,8 +776,8 @@ add_ancestors_cbdata(memberof_cached_value *ancestors, void *callback_data)
|
||||
* could want type to be either "member" or "memberOf" depending on the case.
|
||||
*/
|
||||
int
|
||||
-memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
||||
- MemberOfConfig *config, char **types, plugin_search_entry_callback callback, void *callback_data, int *cached)
|
||||
+memberof_call_foreach_dn(Slapi_PBlock *pb __attribute__((unused)), Slapi_DN *sdn,
|
||||
+ MemberOfConfig *config, char **types, plugin_search_entry_callback callback, void *callback_data, int *cached, PRBool use_grp_cache)
|
||||
{
|
||||
Slapi_PBlock *search_pb = NULL;
|
||||
Slapi_DN *base_sdn = NULL;
|
||||
@@ -792,9 +792,6 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
||||
int free_it = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
- memberof_cached_value *ht_grp = NULL;
|
||||
- memberof_get_groups_data *data = (memberof_get_groups_data*) callback_data;
|
||||
- const char *ndn = slapi_sdn_get_ndn(sdn);
|
||||
|
||||
*cached = 0;
|
||||
|
||||
@@ -802,17 +799,24 @@ memberof_call_foreach_dn(Slapi_PBlock *pb, Slapi_DN *sdn,
|
||||
return (rc);
|
||||
}
|
||||
|
||||
- /* Here we will retrieve the ancestor of sdn.
|
||||
- * The key access is the normalized sdn
|
||||
- * This is done through recursive internal searches of parents
|
||||
- * If the ancestors of sdn are already cached, just use
|
||||
- * this value
|
||||
+ /* This flags indicates memberof_call_foreach_dn is called to retrieve ancestors (groups).
|
||||
+ * To improve performance, it can use a cache. (it will not in case of circular groups)
|
||||
+ * When this flag is true it means no circular group are detected (so far) so we can use the cache
|
||||
*/
|
||||
- if (data && data->use_cache) {
|
||||
+ if (use_grp_cache) {
|
||||
+ /* Here we will retrieve the ancestor of sdn.
|
||||
+ * The key access is the normalized sdn
|
||||
+ * This is done through recursive internal searches of parents
|
||||
+ * If the ancestors of sdn are already cached, just use
|
||||
+ * this value
|
||||
+ */
|
||||
+ memberof_cached_value *ht_grp = NULL;
|
||||
+ const char *ndn = slapi_sdn_get_ndn(sdn);
|
||||
+
|
||||
ht_grp = ancestors_cache_lookup((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);
|
||||
+ slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_call_foreach_dn: Ancestors of %s already cached (%x)\n", ndn, ht_grp);
|
||||
#endif
|
||||
add_ancestors_cbdata(ht_grp, callback_data);
|
||||
*cached = 1;
|
||||
@@ -1106,7 +1110,7 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_replace_dn_from_groups: Ancestors of %s\n", slapi_sdn_get_dn(post_sdn));
|
||||
if((ret = memberof_call_foreach_dn(pb, pre_sdn, config, groupattrs,
|
||||
memberof_replace_dn_type_callback,
|
||||
- &data, &cached)))
|
||||
+ &data, &cached, PR_FALSE)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -2383,7 +2387,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn,
|
||||
slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_get_groups_r: Ancestors of %s\n", slapi_sdn_get_dn(member_sdn));
|
||||
#endif
|
||||
rc = memberof_call_foreach_dn(NULL, member_sdn, config, config->groupattrs,
|
||||
- memberof_get_groups_callback, &member_data, &cached);
|
||||
+ memberof_get_groups_callback, &member_data, &cached, member_data.use_cache);
|
||||
|
||||
merge_ancestors(&member_ndn_val, &member_data, data);
|
||||
if (!cached && member_data.use_cache)
|
||||
@@ -2578,7 +2582,7 @@ memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config,
|
||||
int cached = 0;
|
||||
|
||||
return memberof_call_foreach_dn(pb, group_sdn, config, attrs,
|
||||
- memberof_test_membership_callback, config, &cached);
|
||||
+ memberof_test_membership_callback, config, &cached, PR_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From 8a0b4643e1119e994370089fd52721373e88bb51 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Wed, 29 Mar 2017 10:59:14 +1000
|
||||
Subject: [PATCH] Ticket 49196 - Autotune generates crit messages
|
||||
|
||||
Bug Description: The cache sanity check generates critical messages.
|
||||
|
||||
Fix Description: Make the sanity check generate warning messages.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49196
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/start.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/start.c b/ldap/servers/slapd/back-ldbm/start.c
|
||||
index 759af8a..1ae9858 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/start.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/start.c
|
||||
@@ -265,12 +265,12 @@ ldbm_back_start_autotune(struct ldbminfo *li) {
|
||||
issane = util_is_cachesize_sane(&total_cache_size);
|
||||
if (!issane) {
|
||||
/* Right, it's time to panic */
|
||||
- slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "It is highly likely your memory configuration of all backends will EXCEED your systems memory.\n");
|
||||
- slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "In a future release this WILL prevent server start up. You MUST alter your configuration.\n");
|
||||
- slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "Total entry cache size: %lu B; dbcache size: %lu B; available memory size: %lu B; \n",
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "It is highly likely your memory configuration of all backends will EXCEED your systems memory.\n");
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "In a future release this WILL prevent server start up. You MUST alter your configuration.\n");
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "Total entry cache size: %lu B; dbcache size: %lu B; available memory size: %lu B; \n",
|
||||
(PRUint64)total_cache_size, (PRUint64)li->li_dbcachesize, availpages * pagesize
|
||||
);
|
||||
- slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "%s\n", msg);
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "%s\n", msg);
|
||||
/* WB 2016 - This should be UNCOMMENTED in a future release */
|
||||
/* return SLAPI_FAIL_GENERAL; */
|
||||
}
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From 4e66114109263fff6b13192e07be9bbd9e493fee Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 17 Apr 2017 17:06:19 -0400
|
||||
Subject: [PATCH 1/2] Issue 49221 - During an upgrade the provided localhost
|
||||
name is ignored
|
||||
|
||||
Description: If the FullMachine name, or localhost, is provided in an INF
|
||||
it is ignored during the upgrade the value of nsslapd-localhost
|
||||
from the current server is used instead. We should only override
|
||||
the localhost value if it is missing.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49221
|
||||
|
||||
Reviewed by: nhosoi(Thanks!)
|
||||
---
|
||||
ldap/admin/src/scripts/DSUpdate.pm.in | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/DSUpdate.pm.in b/ldap/admin/src/scripts/DSUpdate.pm.in
|
||||
index e84a9a9..8b24b47 100644
|
||||
--- a/ldap/admin/src/scripts/DSUpdate.pm.in
|
||||
+++ b/ldap/admin/src/scripts/DSUpdate.pm.in
|
||||
@@ -435,7 +435,9 @@ sub initInfFromInst {
|
||||
my $servid = $inst;
|
||||
$servid =~ s/slapd-//;
|
||||
|
||||
- $inf->{General}->{FullMachineName} = $entry->getValue("nsslapd-localhost");
|
||||
+ if (!$inf->{General}->{FullMachineName}) {
|
||||
+ $inf->{General}->{FullMachineName} = $entry->getValue("nsslapd-localhost");
|
||||
+ }
|
||||
$inf->{General}->{SuiteSpotUserID} = $entry->getValue("nsslapd-localuser");
|
||||
$inf->{slapd}->{ServerPort} = $entry->getValue("nsslapd-port");
|
||||
$inf->{slapd}->{ldapifilepath} = $entry->getValue("nsslapd-ldapifilepath");
|
||||
--
|
||||
2.9.3
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,296 @@
|
|||
From 9be74e83539e204e9a56721da5c22bd9abf38195 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 19 Apr 2017 13:41:22 -0400
|
||||
Subject: [PATCH] Ticket 49204 - Fix lower bounds on import autosize + On small
|
||||
VM, autotune breaks the access of the suffixes
|
||||
|
||||
Bug Description:
|
||||
ldif2db in some cases may set a cache of 0, which may y break imports.
|
||||
|
||||
Under memory pressure, the amount of available memory at startup
|
||||
can be so low that the configured cachememsize will be rejected
|
||||
(unwilling to perform).
|
||||
This should leave the cachememsize being "0" (default)
|
||||
This conduct to be unable to access the suffix pages.
|
||||
|
||||
Fix Description:
|
||||
|
||||
* autosize set an incorrect percentage which was too high.
|
||||
* we did not check the lower bound of the allocation
|
||||
so we now set that we must have a minimum allocation.
|
||||
* Set entrycache to a minimal value, even if it looks insane
|
||||
* add a cap on reduction of caches, so we always allocate a few pages
|
||||
at least, and prevent returning 0 to the caller.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49204
|
||||
|
||||
Author: wibrown, tbordaz
|
||||
|
||||
Review by: tbordaz (Thanks mate, great work with this :) )
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/cache.c | 4 +--
|
||||
ldap/servers/slapd/back-ldbm/dblayer.c | 33 +++++++++++++---------
|
||||
ldap/servers/slapd/back-ldbm/dblayer.h | 12 ++++----
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 4 +--
|
||||
.../servers/slapd/back-ldbm/ldbm_instance_config.c | 23 +++++++++++++--
|
||||
ldap/servers/slapd/slapi-private.h | 2 +-
|
||||
ldap/servers/slapd/util.c | 20 +++++++++----
|
||||
7 files changed, 65 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
|
||||
index 0f0cf3b..c6638a2 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/cache.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/cache.c
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
/* static functions */
|
||||
static void entrycache_clear_int(struct cache *cache);
|
||||
-static void entrycache_set_max_size(struct cache *cache, size_t bytes);
|
||||
+static void entrycache_set_max_size(struct cache *cache, uint64_t bytes);
|
||||
static int entrycache_remove_int(struct cache *cache, struct backentry *e);
|
||||
static void entrycache_return(struct cache *cache, struct backentry **bep);
|
||||
static int entrycache_replace(struct cache *cache, struct backentry *olde, struct backentry *newe);
|
||||
@@ -77,7 +77,7 @@ static void entry_lru_verify(struct cache *cache, struct backentry *e, int in);
|
||||
|
||||
static int dn_same_id(const void *bdn, const void *k);
|
||||
static void dncache_clear_int(struct cache *cache);
|
||||
-static void dncache_set_max_size(struct cache *cache, size_t bytes);
|
||||
+static void dncache_set_max_size(struct cache *cache, uint64_t bytes);
|
||||
static int dncache_remove_int(struct cache *cache, struct backdn *dn);
|
||||
static void dncache_return(struct cache *cache, struct backdn **bdn);
|
||||
static int dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn);
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
index 3c1fbb0..f834322 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
@@ -1237,8 +1237,8 @@ no_diskspace(struct ldbminfo *li, int dbenv_flags)
|
||||
struct statvfs db_buf;
|
||||
int using_region_files = !(dbenv_flags & ( DB_PRIVATE | DB_SYSTEM_MEM));
|
||||
/* value of 10 == 10% == little more than the average overhead calculated for very large files on 64-bit system for bdb 4.7 */
|
||||
- PRUint64 expected_siz = li->li_dbcachesize + li->li_dbcachesize/10; /* dbcache + region files */
|
||||
- PRUint64 fsiz;
|
||||
+ uint64_t expected_siz = li->li_dbcachesize + li->li_dbcachesize/10; /* dbcache + region files */
|
||||
+ uint64_t fsiz;
|
||||
char *region_dir;
|
||||
|
||||
if (statvfs(li->li_directory, &db_buf) < 0){
|
||||
@@ -1263,7 +1263,7 @@ no_diskspace(struct ldbminfo *li, int dbenv_flags)
|
||||
li->li_dblayer_private->dblayer_dbhome_directory);
|
||||
return 1;
|
||||
}
|
||||
- fsiz = ((PRUint64)dbhome_buf.f_bavail) * ((PRUint64)dbhome_buf.f_bsize);
|
||||
+ fsiz = ((uint64_t)dbhome_buf.f_bavail) * ((uint64_t)dbhome_buf.f_bsize);
|
||||
region_dir = li->li_dblayer_private->dblayer_dbhome_directory;
|
||||
} else {
|
||||
/* Shared/private memory. No need to check disk space, return success */
|
||||
@@ -1387,12 +1387,17 @@ dblayer_start(struct ldbminfo *li, int dbmode)
|
||||
/* Sanity check on cache size on platforms which allow us to figure out
|
||||
* the available phys mem */
|
||||
slapi_pal_meminfo *mi = spal_meminfo_get();
|
||||
- if (!util_is_cachesize_sane(mi, &(priv->dblayer_cachesize))) {
|
||||
+ util_cachesize_result result = util_is_cachesize_sane(mi, &(priv->dblayer_cachesize));
|
||||
+ if (result == UTIL_CACHESIZE_ERROR) {
|
||||
+ slapi_log_err(SLAPI_LOG_CRIT, "dblayer_start", "Unable to determine if cachesize was valid!!!");
|
||||
+ } else if (result == UTIL_CACHESIZE_REDUCED) {
|
||||
+ /* In some cases we saw this go to 0, prevent this. */
|
||||
+ if (priv->dblayer_cachesize < MINCACHESIZE) {
|
||||
+ priv->dblayer_cachesize = MINCACHESIZE;
|
||||
+ }
|
||||
/* Oops---looks like the admin misconfigured, let's warn them */
|
||||
- slapi_log_err(SLAPI_LOG_WARNING,"dblayer_start", "Likely CONFIGURATION ERROR -"
|
||||
- "dbcachesize is configured to use more than the available "
|
||||
- "physical memory, decreased to the largest available size (%"PRIu64" bytes).\n",
|
||||
- priv->dblayer_cachesize);
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "dblayer_start", "Likely CONFIGURATION ERROR - dbcachesize is configured to use more than the available "
|
||||
+ "memory, decreased to (%"PRIu64" bytes).\n", priv->dblayer_cachesize);
|
||||
li->li_dbcachesize = priv->dblayer_cachesize;
|
||||
}
|
||||
spal_meminfo_destroy(mi);
|
||||
@@ -3816,7 +3821,7 @@ static const u_int32_t default_flags = DB_NEXT;
|
||||
typedef struct txn_test_iter {
|
||||
DB *db;
|
||||
DBC *cur;
|
||||
- size_t cnt;
|
||||
+ uint64_t cnt;
|
||||
const char *attr;
|
||||
u_int32_t flags;
|
||||
backend *be;
|
||||
@@ -3938,10 +3943,10 @@ static int txn_test_threadmain(void *param)
|
||||
Object *inst_obj;
|
||||
int rc = 0;
|
||||
txn_test_iter **ttilist = NULL;
|
||||
- size_t tticnt = 0;
|
||||
+ uint64_t tticnt = 0;
|
||||
DB_TXN *txn = NULL;
|
||||
txn_test_cfg cfg = {0};
|
||||
- size_t counter = 0;
|
||||
+ uint64_t counter = 0;
|
||||
char keybuf[8192];
|
||||
char databuf[8192];
|
||||
int dbattempts = 0;
|
||||
@@ -4062,9 +4067,9 @@ retry_txn:
|
||||
if (!rc) {
|
||||
DBT key;
|
||||
DBT data;
|
||||
- size_t ii;
|
||||
- size_t donecnt = 0;
|
||||
- size_t cnt = 0;
|
||||
+ uint64_t ii;
|
||||
+ uint64_t donecnt = 0;
|
||||
+ uint64_t cnt = 0;
|
||||
|
||||
/* phase 1 - open a cursor to each db */
|
||||
if (cfg.verbose) {
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
index 816c943..77b04fa 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
|
||||
@@ -90,8 +90,8 @@ struct dblayer_private
|
||||
int dblayer_ncache;
|
||||
int dblayer_previous_ncache;
|
||||
int dblayer_tx_max;
|
||||
- size_t dblayer_cachesize;
|
||||
- size_t dblayer_previous_cachesize; /* Cache size when we last shut down--
|
||||
+ uint64_t dblayer_cachesize;
|
||||
+ uint64_t dblayer_previous_cachesize; /* Cache size when we last shut down--
|
||||
* used to determine if we delete
|
||||
* the mpool */
|
||||
int dblayer_recovery_required;
|
||||
@@ -102,15 +102,15 @@ struct dblayer_private
|
||||
int dblayer_durable_transactions;
|
||||
int dblayer_checkpoint_interval;
|
||||
int dblayer_circular_logging;
|
||||
- size_t dblayer_page_size; /* db page size if configured,
|
||||
+ uint64_t dblayer_page_size; /* db page size if configured,
|
||||
* otherwise default to DBLAYER_PAGESIZE */
|
||||
- size_t dblayer_index_page_size; /* db index page size if configured,
|
||||
+ uint64_t dblayer_index_page_size; /* db index page size if configured,
|
||||
* otherwise default to
|
||||
* DBLAYER_INDEX_PAGESIZE */
|
||||
int dblayer_idl_divisor; /* divide page size by this to get IDL
|
||||
* size */
|
||||
- size_t dblayer_logfile_size; /* How large can one logfile be ? */
|
||||
- size_t dblayer_logbuf_size; /* how large log buffer can be */
|
||||
+ uint64_t dblayer_logfile_size; /* How large can one logfile be ? */
|
||||
+ uint64_t dblayer_logbuf_size; /* how large log buffer can be */
|
||||
int dblayer_file_mode; /* pmode for files we create */
|
||||
int dblayer_verbose; /* Get libdb to exhale debugging info */
|
||||
int dblayer_debug; /* Will libdb emit debugging info into
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index d5120d3..401cd60 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -1582,9 +1582,9 @@ static config_info ldbm_config[] = {
|
||||
{CONFIG_DB_DEBUG_CHECKPOINTING, CONFIG_TYPE_ONOFF, "off", &ldbm_config_db_debug_checkpointing_get, &ldbm_config_db_debug_checkpointing_set, 0},
|
||||
{CONFIG_DB_HOME_DIRECTORY, CONFIG_TYPE_STRING, "", &ldbm_config_db_home_directory_get, &ldbm_config_db_home_directory_set, 0},
|
||||
{CONFIG_IMPORT_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "-1", &ldbm_config_import_cache_autosize_get, &ldbm_config_import_cache_autosize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
- {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "0", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, 0},
|
||||
+ {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "10", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, 0},
|
||||
{CONFIG_CACHE_AUTOSIZE_SPLIT, CONFIG_TYPE_INT, "40", &ldbm_config_cache_autosize_split_get, &ldbm_config_cache_autosize_split_set, 0},
|
||||
- {CONFIG_IMPORT_CACHESIZE, CONFIG_TYPE_SIZE_T, "20000000", &ldbm_config_import_cachesize_get, &ldbm_config_import_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
+ {CONFIG_IMPORT_CACHESIZE, CONFIG_TYPE_SIZE_T, "16777216", &ldbm_config_import_cachesize_get, &ldbm_config_import_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_IDL_SWITCH, CONFIG_TYPE_STRING, "new", &ldbm_config_idl_get_idl_new, &ldbm_config_idl_set_tune, CONFIG_FLAG_ALWAYS_SHOW},
|
||||
{CONFIG_IDL_UPDATE, CONFIG_TYPE_ONOFF, "on", &ldbm_config_idl_get_update, &ldbm_config_idl_set_update, 0},
|
||||
{CONFIG_BYPASS_FILTER_TEST, CONFIG_TYPE_STRING, "on", &ldbm_config_get_bypass_filter_test, &ldbm_config_set_bypass_filter_test, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
index 62cdbc3..36d830d 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
@@ -93,6 +93,7 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
|
||||
int retval = LDAP_SUCCESS;
|
||||
size_t val = (size_t) value;
|
||||
uint64_t delta = 0;
|
||||
+ uint64_t delta_original = 0;
|
||||
|
||||
/* Do whatever we can to make sure the data is ok. */
|
||||
/* There is an error here. We check the new val against our current mem-alloc
|
||||
@@ -108,18 +109,34 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
|
||||
if (apply) {
|
||||
if (val > inst->inst_cache.c_maxsize) {
|
||||
delta = val - inst->inst_cache.c_maxsize;
|
||||
+ delta_original = delta;
|
||||
|
||||
util_cachesize_result sane;
|
||||
slapi_pal_meminfo *mi = spal_meminfo_get();
|
||||
sane = util_is_cachesize_sane(mi, &delta);
|
||||
spal_meminfo_destroy(mi);
|
||||
|
||||
- if (sane != UTIL_CACHESIZE_VALID){
|
||||
- slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: cachememsize value is too large.");
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "cachememsize value is too large.\n");
|
||||
+ if (sane == UTIL_CACHESIZE_ERROR){
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: unable to determine system memory limits.");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "Enable to determine system memory limits.\n");
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ } else if (sane == UTIL_CACHESIZE_REDUCED) {
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_instance_config_cachememsize_set", "delta +%"PRIu64" of request %"PRIu64" reduced to %"PRIu64"\n", delta_original, val, delta);
|
||||
+ /*
|
||||
+ * This works as: value = 100
|
||||
+ * delta_original to inst, 20;
|
||||
+ * delta reduced to 5:
|
||||
+ * 100 - (20 - 5) == 85;
|
||||
+ * so if you recalculated delta now (val - inst), it would be 5.
|
||||
+ */
|
||||
+ val = val - (delta_original - delta);
|
||||
}
|
||||
}
|
||||
+ if (inst->inst_cache.c_maxsize < MINCACHESIZE || val < MINCACHESIZE) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "force a minimal value %"PRIu64"\n", MINCACHESIZE);
|
||||
+ /* This value will trigger an autotune next start up, but it should increase only */
|
||||
+ val = MINCACHESIZE;
|
||||
+ }
|
||||
cache_set_max_size(&(inst->inst_cache), val, CACHE_TYPE_ENTRY);
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
||||
index 0c76580..d9547d8 100644
|
||||
--- a/ldap/servers/slapd/slapi-private.h
|
||||
+++ b/ldap/servers/slapd/slapi-private.h
|
||||
@@ -1392,7 +1392,7 @@ typedef enum _util_cachesize_result {
|
||||
* \return util_cachesize_result.
|
||||
* \sa util_cachesize_result, spal_meminfo_get
|
||||
*/
|
||||
-util_cachesize_result util_is_cachesize_sane(slapi_pal_meminfo *mi, size_t *cachesize);
|
||||
+util_cachesize_result util_is_cachesize_sane(slapi_pal_meminfo *mi, uint64_t *cachesize);
|
||||
|
||||
/**
|
||||
* Retrieve the number of threads the server should run with based on this hardware.
|
||||
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
|
||||
index 012e83d..4ff6d41 100644
|
||||
--- a/ldap/servers/slapd/util.c
|
||||
+++ b/ldap/servers/slapd/util.c
|
||||
@@ -1468,16 +1468,26 @@ util_is_cachesize_sane(slapi_pal_meminfo *mi, uint64_t *cachesize)
|
||||
return UTIL_CACHESIZE_ERROR;
|
||||
}
|
||||
|
||||
+ util_cachesize_result result = UTIL_CACHESIZE_VALID;
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Available bytes %"PRIu64", requested bytes %"PRIu64"\n", mi->system_available_bytes, *cachesize);
|
||||
if (*cachesize > mi->system_available_bytes) {
|
||||
- /* Since we are ask for more than what's available, we give 3/4 of the remaining.
|
||||
+ /* Since we are ask for more than what's available, we give 1/2 of the remaining.
|
||||
* the remaining system mem to the cachesize instead, and log a warning
|
||||
*/
|
||||
- *cachesize = (mi->system_available_bytes * 0.75);
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Adjusted cachesize to %"PRIu64"\n", *cachesize);
|
||||
- return UTIL_CACHESIZE_REDUCED;
|
||||
+ uint64_t adjust_cachesize = (mi->system_available_bytes * 0.5);
|
||||
+ if (adjust_cachesize > *cachesize) {
|
||||
+ slapi_log_err(SLAPI_LOG_CRIT, "util_is_cachesize_sane", "Invalid adjusted cachesize is greater than request %"PRIu64, adjust_cachesize);
|
||||
+ return UTIL_CACHESIZE_ERROR;
|
||||
+ }
|
||||
+ if (adjust_cachesize < (16 * mi->pagesize_bytes)) {
|
||||
+ /* At minimum respond with 16 pages - that's 64k on x86_64 */
|
||||
+ adjust_cachesize = 16 * mi->pagesize_bytes;
|
||||
+ }
|
||||
+ *cachesize = adjust_cachesize;
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Adjusted cachesize down to %"PRIu64"\n", *cachesize);
|
||||
+ result = UTIL_CACHESIZE_REDUCED;
|
||||
}
|
||||
- return UTIL_CACHESIZE_VALID;
|
||||
+ return result;
|
||||
}
|
||||
|
||||
long
|
||||
--
|
||||
2.9.3
|
||||
|
328
SOURCES/0030-Ticket-49231-fix-sasl-mech-handling.patch
Normal file
328
SOURCES/0030-Ticket-49231-fix-sasl-mech-handling.patch
Normal file
|
@ -0,0 +1,328 @@
|
|||
From 88a0ce3c3f89244a77dfa618c8a5064bda30f376 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Wed, 26 Apr 2017 15:48:30 +1000
|
||||
Subject: [PATCH] Ticket 49231 - fix sasl mech handling
|
||||
|
||||
Bug Description: In our sasl code we had two issues. One was that
|
||||
we did not correctly apply the list of sasl allowed mechs to our
|
||||
rootdse list in ids_sasl_listmech. The second was that on config
|
||||
reset, we did not correctly set null to the value.
|
||||
|
||||
Fix Description: Fix the handling of the mech lists to allow
|
||||
reset, and allow the mech list to be updated properly.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49231
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/suites/sasl/allowed_mechs.py | 43 ++++++++++++++++++
|
||||
ldap/servers/slapd/charray.c | 48 +++++++++++++++++---
|
||||
ldap/servers/slapd/libglobs.c | 62 ++++++++++++++++++++------
|
||||
ldap/servers/slapd/proto-slap.h | 1 +
|
||||
ldap/servers/slapd/saslbind.c | 21 ++++++++-
|
||||
ldap/servers/slapd/slap.h | 1 +
|
||||
ldap/servers/slapd/slapi-private.h | 1 +
|
||||
7 files changed, 156 insertions(+), 21 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/allowed_mechs.py b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
new file mode 100644
|
||||
index 0000000..a3e385e
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
@@ -0,0 +1,43 @@
|
||||
+# --- 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 ldap
|
||||
+
|
||||
+import time
|
||||
+
|
||||
+from lib389.topologies import topology_st
|
||||
+
|
||||
+def test_sasl_allowed_mechs(topology_st):
|
||||
+ standalone = topology_st.standalone
|
||||
+
|
||||
+ # Get the supported mechs. This should contain PLAIN, GSSAPI, EXTERNAL at least
|
||||
+ orig_mechs = standalone.rootdse.supported_sasl()
|
||||
+ print(orig_mechs)
|
||||
+ assert('GSSAPI' in orig_mechs)
|
||||
+ assert('PLAIN' in orig_mechs)
|
||||
+ assert('EXTERNAL' in orig_mechs)
|
||||
+
|
||||
+ # Now edit the supported mechs. CHeck them again.
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'EXTERNAL, PLAIN')
|
||||
+
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ print(limit_mechs)
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+
|
||||
+ # Do a config reset
|
||||
+ standalone.config.reset('nsslapd-allowed-sasl-mechanisms')
|
||||
+
|
||||
+ # check the supported list is the same as our first check.
|
||||
+ final_mechs = standalone.rootdse.supported_sasl()
|
||||
+ print(final_mechs)
|
||||
+ assert(set(final_mechs) == set(orig_mechs))
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/charray.c b/ldap/servers/slapd/charray.c
|
||||
index 5551dcc..6b89714 100644
|
||||
--- a/ldap/servers/slapd/charray.c
|
||||
+++ b/ldap/servers/slapd/charray.c
|
||||
@@ -348,8 +348,9 @@ slapi_str2charray_ext( char *str, char *brkstr, int allow_dups )
|
||||
}
|
||||
}
|
||||
|
||||
- if ( !dup_found )
|
||||
+ if ( !dup_found ) {
|
||||
res[i++] = slapi_ch_strdup( s );
|
||||
+ }
|
||||
}
|
||||
res[i] = NULL;
|
||||
|
||||
@@ -413,10 +414,11 @@ charray_subtract(char **a, char **b, char ***c)
|
||||
char **bp, **cp, **tmp;
|
||||
char **p;
|
||||
|
||||
- if (c)
|
||||
+ if (c) {
|
||||
tmp = *c = cool_charray_dup(a);
|
||||
- else
|
||||
+ } else {
|
||||
tmp = a;
|
||||
+ }
|
||||
|
||||
for (cp = tmp; cp && *cp; cp++) {
|
||||
for (bp = b; bp && *bp; bp++) {
|
||||
@@ -433,12 +435,48 @@ charray_subtract(char **a, char **b, char ***c)
|
||||
for (p = cp+1; *p && *p == (char *)SUBTRACT_DEL; p++)
|
||||
;
|
||||
*cp = *p;
|
||||
- if (*p == NULL)
|
||||
+ if (*p == NULL) {
|
||||
break;
|
||||
- else
|
||||
+ } else {
|
||||
*p = SUBTRACT_DEL;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Provides the intersection of two arrays.
|
||||
+ * IE if you have:
|
||||
+ * (A, B, C)
|
||||
+ * (B, D, E)
|
||||
+ * result is (B,)
|
||||
+ * a and b are NOT consumed in the process.
|
||||
+ */
|
||||
+char **
|
||||
+charray_intersection(char **a, char **b) {
|
||||
+ char **result;
|
||||
+ size_t rp = 0;
|
||||
+
|
||||
+ if (a == NULL || b == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ size_t a_len = 0;
|
||||
+ /* Find how long A is. */
|
||||
+ for (; a[a_len] != NULL; a_len++);
|
||||
+
|
||||
+ /* Allocate our result, it can't be bigger than A */
|
||||
+ result = (char **)slapi_ch_calloc(1, sizeof(char *) * (a_len + 1));
|
||||
+
|
||||
+ /* For each in A, see if it's in b */
|
||||
+ for (size_t i = 0; a[i] != NULL; i++) {
|
||||
+ if (charray_get_index(b, a[i]) != -1) {
|
||||
+ result[rp] = slapi_ch_strdup(a[i]);
|
||||
+ rp++;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ return result;
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index 0e818a9..2fc9fbf 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -7090,9 +7090,30 @@ config_set_entryusn_import_init( const char *attrname, char *value,
|
||||
return retVal;
|
||||
}
|
||||
|
||||
+char **
|
||||
+config_get_allowed_sasl_mechs_array(void)
|
||||
+{
|
||||
+ /*
|
||||
+ * array of mechs. If is null, returns NULL thanks to ch_array_dup.
|
||||
+ * Caller must free!
|
||||
+ */
|
||||
+ char **retVal;
|
||||
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||
+
|
||||
+ CFG_LOCK_READ(slapdFrontendConfig);
|
||||
+ retVal = slapi_ch_array_dup(slapdFrontendConfig->allowed_sasl_mechs_array);
|
||||
+ CFG_UNLOCK_READ(slapdFrontendConfig);
|
||||
+
|
||||
+ return retVal;
|
||||
+}
|
||||
+
|
||||
char *
|
||||
-config_get_allowed_sasl_mechs()
|
||||
+config_get_allowed_sasl_mechs(void)
|
||||
{
|
||||
+ /*
|
||||
+ * Space seperated list of allowed mechs
|
||||
+ * if this is NULL, means *all* mechs are allowed!
|
||||
+ */
|
||||
char *retVal;
|
||||
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||
|
||||
@@ -7113,22 +7134,35 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
- /* cyrus sasl doesn't like comma separated lists */
|
||||
- remove_commas(value);
|
||||
+ /* During a reset, the value is "", so we have to handle this case. */
|
||||
+ if (strcmp(value, "") != 0) {
|
||||
+ /* cyrus sasl doesn't like comma separated lists */
|
||||
+ remove_commas(value);
|
||||
+
|
||||
+ if(invalid_sasl_mech(value)){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR,"config_set_allowed_sasl_mechs",
|
||||
+ "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
+ "characters, upto 20 characters, that are upper-case letters, "
|
||||
+ "digits, hyphens, or underscores\n", value);
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
|
||||
- if(invalid_sasl_mech(value)){
|
||||
- slapi_log_err(SLAPI_LOG_ERR,"config_set_allowed_sasl_mechs",
|
||||
- "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
- "characters, upto 20 characters, that are upper-case letters, "
|
||||
- "digits, hyphens, or underscores\n", value);
|
||||
- return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
+ slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
|
||||
+ slapi_ch_array_free(slapdFrontendConfig->allowed_sasl_mechs_array);
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs_array = slapi_str2charray_ext(value, " ", 0);
|
||||
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
+ } else {
|
||||
+ /* If this value is "", we need to set the list to *all* possible mechs */
|
||||
+ CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
+ slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
|
||||
+ slapi_ch_array_free(slapdFrontendConfig->allowed_sasl_mechs_array);
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs = NULL;
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs_array = NULL;
|
||||
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
}
|
||||
|
||||
- CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
- slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
|
||||
- slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
|
||||
- CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
-
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index fdb4bf0..9696ead 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -553,6 +553,7 @@ size_t config_get_ndn_cache_size(void);
|
||||
int config_get_ndn_cache_enabled(void);
|
||||
int config_get_return_orig_type_switch(void);
|
||||
char *config_get_allowed_sasl_mechs(void);
|
||||
+char **config_get_allowed_sasl_mechs_array(void);
|
||||
int config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
int config_get_schemamod(void);
|
||||
int config_set_ignore_vattrs(const char *attrname, char *value, char *errorbuf, int apply);
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 2d6fb64..6e544e6 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -744,7 +744,10 @@ void ids_sasl_server_new(Connection *conn)
|
||||
*/
|
||||
char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
{
|
||||
- char **ret, **others;
|
||||
+ char **ret;
|
||||
+ char **config_ret;
|
||||
+ char **sup_ret;
|
||||
+ char **others;
|
||||
const char *str;
|
||||
char *dupstr;
|
||||
sasl_conn_t *sasl_conn;
|
||||
@@ -754,7 +757,7 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
PR_ASSERT(pb);
|
||||
|
||||
/* hard-wired mechanisms and slapi plugin registered mechanisms */
|
||||
- ret = slapi_get_supported_saslmechanisms_copy();
|
||||
+ sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
if (pb->pb_conn == NULL) return ret;
|
||||
|
||||
@@ -777,6 +780,20 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
}
|
||||
PR_ExitMonitor(pb->pb_conn->c_mutex);
|
||||
|
||||
+ /* Get the servers "allowed" list */
|
||||
+ config_ret = config_get_allowed_sasl_mechs_array();
|
||||
+
|
||||
+ /* Remove any content that isn't in the allowed list */
|
||||
+ if (config_ret != NULL) {
|
||||
+ /* Get the set of supported mechs in the insection of the two */
|
||||
+ ret = charray_intersection(sup_ret, config_ret);
|
||||
+ charray_free(sup_ret);
|
||||
+ charray_free(config_ret);
|
||||
+ } else {
|
||||
+ /* The allowed list was empty, just take our supported list. */
|
||||
+ ret = sup_ret;
|
||||
+ }
|
||||
+
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "<=\n");
|
||||
|
||||
return ret;
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index abfad20..5e44cc8 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -2577,6 +2577,7 @@ typedef struct _slapdFrontendConfig {
|
||||
int pagedsizelimit;
|
||||
char *default_naming_context; /* Default naming context (normalized) */
|
||||
char *allowed_sasl_mechs; /* comma/space separated list of allowed sasl mechs */
|
||||
+ char **allowed_sasl_mechs_array; /* Array of allow sasl mechs */
|
||||
int sasl_max_bufsize; /* The max receive buffer size for SASL */
|
||||
|
||||
/* disk monitoring */
|
||||
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
||||
index d9547d8..3f732e8 100644
|
||||
--- a/ldap/servers/slapd/slapi-private.h
|
||||
+++ b/ldap/servers/slapd/slapi-private.h
|
||||
@@ -831,6 +831,7 @@ int charray_remove(char **a, const char *s, int freeit);
|
||||
char ** cool_charray_dup( char **a );
|
||||
void cool_charray_free( char **array );
|
||||
void charray_subtract( char **a, char **b, char ***c );
|
||||
+char **charray_intersection(char **a, char **b);
|
||||
int charray_get_index(char **array, char *s);
|
||||
int charray_normdn_add(char ***chararray, char *dn, char *errstr);
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
From 91a162d66c2fe239c009f1ee16974d310b333e7e Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Fri, 21 Apr 2017 17:16:55 +0200
|
||||
Subject: [PATCH] Ticket 49230 - slapi_register_plugin creates config entry
|
||||
where it should not
|
||||
|
||||
Bug Description:
|
||||
slapi-register-plugin systematically create an entry under
|
||||
'cn=plugins,cn=config' because it is not taking into account
|
||||
the flag 'add_entry in 'plugin_setup'.
|
||||
|
||||
This is potentially a regression introduced by
|
||||
https://pagure.io/389-ds-base/issue/49066 (TBC)
|
||||
|
||||
Fix Description:
|
||||
Test 'add_entry' before adding the entry
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49230
|
||||
|
||||
Review by: Mark Reynolds, William Brown
|
||||
---
|
||||
ldap/servers/slapd/plugin.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
|
||||
index ac8306f..a5e0724 100644
|
||||
--- a/ldap/servers/slapd/plugin.c
|
||||
+++ b/ldap/servers/slapd/plugin.c
|
||||
@@ -3132,11 +3132,13 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group,
|
||||
add_plugin_entry_dn(dn_copy);
|
||||
}
|
||||
|
||||
- /* make a copy of the plugin entry for our own use because it will
|
||||
- be freed later by the caller */
|
||||
- Slapi_Entry *e_copy = slapi_entry_dup(plugin_entry);
|
||||
- /* new_plugin_entry(&plugin_entries, plugin_entry, plugin); */
|
||||
- new_plugin_entry(&dep_plugin_entries, e_copy, plugin);
|
||||
+ if (add_entry) {
|
||||
+ /* make a copy of the plugin entry for our own use because it will
|
||||
+ be freed later by the caller */
|
||||
+ Slapi_Entry *e_copy = slapi_entry_dup(plugin_entry);
|
||||
+ /* new_plugin_entry(&plugin_entries, plugin_entry, plugin); */
|
||||
+ new_plugin_entry(&dep_plugin_entries, e_copy, plugin);
|
||||
+ }
|
||||
|
||||
PLUGIN_CLEANUP:
|
||||
if (status) {
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
From e5f78f9f6a8cab7bfbd33e14912508183f9da283 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 20 Apr 2017 15:01:33 -0400
|
||||
Subject: [PATCH] Issue 49227 - ldapsearch for nsslapd-errorlog-level returns
|
||||
incorrect values
|
||||
|
||||
Bug Description: ldapsearch for the error log level returns the internal
|
||||
bitmask value and not the value set in cn=config.
|
||||
|
||||
Fix Description: When setting the error log level store the initial/untouched
|
||||
value in the config entry first, then set the bitmasked
|
||||
global log level variable.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49227
|
||||
|
||||
Reviewed by: nhosoi(Thanks!)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49227_test.py | 111 ++++++++++++++++++++++++++
|
||||
ldap/servers/slapd/configdse.c | 4 +-
|
||||
ldap/servers/slapd/libglobs.c | 11 +--
|
||||
ldap/servers/slapd/slap.h | 3 +-
|
||||
4 files changed, 121 insertions(+), 8 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49227_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49227_test.py b/dirsrvtests/tests/tickets/ticket49227_test.py
|
||||
new file mode 100644
|
||||
index 0000000..86e0b9a
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49227_test.py
|
||||
@@ -0,0 +1,111 @@
|
||||
+import os
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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__)
|
||||
+DEFAULT_LEVEL = "16384"
|
||||
+
|
||||
+
|
||||
+def set_level(topo, level):
|
||||
+ ''' Set the error log level
|
||||
+ '''
|
||||
+ try:
|
||||
+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', level)])
|
||||
+ time.sleep(1)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to set loglevel to %s - error: %s' % (level, str(e)))
|
||||
+ assert False
|
||||
+
|
||||
+
|
||||
+def get_level(topo):
|
||||
+ ''' Set the error log level
|
||||
+ '''
|
||||
+ try:
|
||||
+ config = topo.standalone.search_s("cn=config", ldap.SCOPE_BASE, "objectclass=top")
|
||||
+ time.sleep(1)
|
||||
+ return config[0].getValue('nsslapd-errorlog-level')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Failed to get loglevel - error: %s' % (str(e)))
|
||||
+ assert False
|
||||
+
|
||||
+
|
||||
+def get_log_size(topo):
|
||||
+ ''' Get the errors log size
|
||||
+ '''
|
||||
+ statinfo = os.stat(topo.standalone.errlog)
|
||||
+ return statinfo.st_size
|
||||
+
|
||||
+
|
||||
+def test_ticket49227(topo):
|
||||
+ """Set the error log to varying levels, and make sure a search for that value
|
||||
+ reflects the expected value (not the bitmasked value.
|
||||
+ """
|
||||
+ log_size = get_log_size(topo)
|
||||
+
|
||||
+ # Check the default level
|
||||
+ level = get_level(topo)
|
||||
+ if level != DEFAULT_LEVEL:
|
||||
+ log.fatal('Incorrect default logging level: %s' % (level))
|
||||
+ assert False
|
||||
+
|
||||
+ # Set connection logging
|
||||
+ set_level(topo, '8')
|
||||
+ level = get_level(topo)
|
||||
+ if level != '8':
|
||||
+ log.fatal('Incorrect connection logging level: %s' % (level))
|
||||
+ assert False
|
||||
+
|
||||
+ # Check the actual log
|
||||
+ new_size = get_log_size(topo)
|
||||
+ if new_size == log_size:
|
||||
+ # Size should be different
|
||||
+ log.fatal('Connection logging is not working')
|
||||
+ assert False
|
||||
+
|
||||
+ # Set default logging using zero
|
||||
+ set_level(topo, '0')
|
||||
+ log_size = get_log_size(topo)
|
||||
+ level = get_level(topo)
|
||||
+ if level != DEFAULT_LEVEL:
|
||||
+ log.fatal('Incorrect default logging level: %s' % (level))
|
||||
+ assert False
|
||||
+
|
||||
+ # Check the actual log
|
||||
+ new_size = get_log_size(topo)
|
||||
+ if new_size != log_size:
|
||||
+ # Size should be the size
|
||||
+ log.fatal('Connection logging is still on')
|
||||
+ assert False
|
||||
+
|
||||
+ # Set default logging using the default value
|
||||
+ set_level(topo, DEFAULT_LEVEL)
|
||||
+ level = get_level(topo)
|
||||
+ if level != DEFAULT_LEVEL:
|
||||
+ log.fatal('Incorrect default logging level: %s' % (level))
|
||||
+ assert False
|
||||
+
|
||||
+ # Check the actual log
|
||||
+ new_size = get_log_size(topo)
|
||||
+ if new_size != log_size:
|
||||
+ # Size should be the size
|
||||
+ log.fatal('Connection logging is still on')
|
||||
+ 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/configdse.c b/ldap/servers/slapd/configdse.c
|
||||
index 78162c9..08d1ace 100644
|
||||
--- a/ldap/servers/slapd/configdse.c
|
||||
+++ b/ldap/servers/slapd/configdse.c
|
||||
@@ -404,12 +404,12 @@ modify_config_dse(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, in
|
||||
config_attr);
|
||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||
} else if (ignore_attr_type(config_attr)) {
|
||||
- slapi_log_err(SLAPI_LOG_WARNING, "modify_config_dse",
|
||||
+ slapi_log_err(SLAPI_LOG_CONFIG, "modify_config_dse",
|
||||
"Modification of attribute \"%s\" is not allowed, ignoring!\n",
|
||||
config_attr);
|
||||
} else if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
|
||||
if (apply_mods) { /* log warning once */
|
||||
- slapi_log_err(SLAPI_LOG_WARNING, "modify_config_dse",
|
||||
+ slapi_log_err(SLAPI_LOG_CONFIG, "modify_config_dse",
|
||||
"Adding configuration attribute \"%s\"\n",
|
||||
config_attr);
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index 2fc9fbf..bb51827 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -308,7 +308,7 @@ static struct config_get_and_set {
|
||||
{CONFIG_LOGLEVEL_ATTRIBUTE, config_set_errorlog_level,
|
||||
NULL, 0,
|
||||
(void**)&global_slapdFrontendConfig.errorloglevel,
|
||||
- CONFIG_SPECIAL_ERRORLOGLEVEL, NULL, SLAPD_DEFAULT_ERRORLOG_LEVEL_STR},
|
||||
+ CONFIG_SPECIAL_ERRORLOGLEVEL, NULL, SLAPD_DEFAULT_FE_ERRORLOG_LEVEL_STR},
|
||||
{CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, NULL,
|
||||
log_set_logging, SLAPD_ERROR_LOG,
|
||||
(void**)&global_slapdFrontendConfig.errorlog_logging_enabled,
|
||||
@@ -1597,7 +1597,7 @@ FrontendConfig_init(void) {
|
||||
cfg->errorlog_minfreespace = SLAPD_DEFAULT_LOG_MINFREESPACE;
|
||||
cfg->errorlog_exptime = SLAPD_DEFAULT_LOG_EXPTIME;
|
||||
cfg->errorlog_exptimeunit = slapi_ch_strdup(SLAPD_INIT_LOG_EXPTIMEUNIT);
|
||||
- cfg->errorloglevel = SLAPD_DEFAULT_ERRORLOG_LEVEL;
|
||||
+ cfg->errorloglevel = SLAPD_DEFAULT_FE_ERRORLOG_LEVEL;
|
||||
|
||||
init_auditlog_logging_enabled = cfg->auditlog_logging_enabled = LDAP_OFF;
|
||||
cfg->auditlog_mode = slapi_ch_strdup(SLAPD_INIT_LOG_MODE);
|
||||
@@ -4474,9 +4474,10 @@ config_set_errorlog_level( const char *attrname, char *value, char *errorbuf, in
|
||||
|
||||
if ( apply ) {
|
||||
CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
- level |= SLAPD_DEFAULT_ERRORLOG_LEVEL; /* Always apply the new default error levels for now */
|
||||
- slapd_ldap_debug = level;
|
||||
slapdFrontendConfig->errorloglevel = level;
|
||||
+ /* Set the internal value - apply the default error level */
|
||||
+ level |= SLAPD_DEFAULT_ERRORLOG_LEVEL;
|
||||
+ slapd_ldap_debug = level;
|
||||
CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
}
|
||||
return retVal;
|
||||
@@ -5771,7 +5772,7 @@ config_get_errorlog_level(){
|
||||
retVal = slapdFrontendConfig->errorloglevel;
|
||||
CFG_UNLOCK_READ(slapdFrontendConfig);
|
||||
|
||||
- return retVal;
|
||||
+ return retVal |= SLAPD_DEFAULT_ERRORLOG_LEVEL;
|
||||
}
|
||||
|
||||
/* return integer -- don't worry about locking similar to config_check_referral_mode
|
||||
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
||||
index 5e44cc8..04c9b79 100644
|
||||
--- a/ldap/servers/slapd/slap.h
|
||||
+++ b/ldap/servers/slapd/slap.h
|
||||
@@ -343,7 +343,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */
|
||||
* LDAP_DEBUG_WARNING | LDAP_DEBUG_NOTICE | LDAP_DEBUG_INFO)
|
||||
*/
|
||||
#define SLAPD_DEFAULT_ERRORLOG_LEVEL 266354688
|
||||
-#define SLAPD_DEFAULT_ERRORLOG_LEVEL_STR "266354688"
|
||||
+#define SLAPD_DEFAULT_FE_ERRORLOG_LEVEL 16384 /* frontend log level */
|
||||
+#define SLAPD_DEFAULT_FE_ERRORLOG_LEVEL_STR "16384"
|
||||
#define SLAPD_DEFAULT_ACCESSLOG_LEVEL 256
|
||||
#define SLAPD_DEFAULT_ACCESSLOG_LEVEL_STR "256"
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
57
SOURCES/0033-Ticket-48989-fix-perf-counters.patch
Normal file
57
SOURCES/0033-Ticket-48989-fix-perf-counters.patch
Normal file
|
@ -0,0 +1,57 @@
|
|||
From a7b9a9ddbff47c2226e60e403374d5e451fac344 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 2 May 2017 13:48:33 -0400
|
||||
Subject: [PATCH] Ticket 48989 - fix perf counters
|
||||
|
||||
Description: There was a copy & paste error where page_access_rate
|
||||
was added, but it listed the wrong attribute name. However,
|
||||
the page_access_rate formula doesn't make sense, nor are
|
||||
there more page stats to use from Berklely DB. Because
|
||||
of this I just removed page_access_rate.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48989
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 18a77e957119bd9994833b7290747f99d73b3745)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/perfctrs.c | 3 ---
|
||||
ldap/servers/slapd/back-ldbm/perfctrs.h | 1 -
|
||||
2 files changed, 4 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/perfctrs.c b/ldap/servers/slapd/back-ldbm/perfctrs.c
|
||||
index 5929dea..9132097 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/perfctrs.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/perfctrs.c
|
||||
@@ -165,7 +165,6 @@ void perfctrs_update(perfctrs_private *priv, DB_ENV *db_env)
|
||||
if (0 == ret) {
|
||||
#define ONEG 1073741824
|
||||
perf->cache_size_bytes = mpstat->st_gbytes * ONEG + mpstat->st_bytes;
|
||||
- perf->page_access_rate = mpstat->st_cache_hit + mpstat->st_cache_miss;
|
||||
perf->cache_hit = mpstat->st_cache_hit;
|
||||
perf->cache_try = mpstat->st_cache_hit + mpstat->st_cache_miss;
|
||||
perf->page_create_rate = mpstat->st_page_create;
|
||||
@@ -257,8 +256,6 @@ static SlapiLDBMPerfctrATMap perfctr_at_map[] = {
|
||||
offsetof( performance_counters, log_write_rate ) },
|
||||
{ SLAPI_LDBM_PERFCTR_AT_PREFIX "longest-chain-length",
|
||||
offsetof( performance_counters, longest_chain_length ) },
|
||||
- { SLAPI_LDBM_PERFCTR_AT_PREFIX "objects-locked",
|
||||
- offsetof( performance_counters, page_access_rate ) },
|
||||
{ SLAPI_LDBM_PERFCTR_AT_PREFIX "page-create-rate",
|
||||
offsetof( performance_counters, page_create_rate ) },
|
||||
{ SLAPI_LDBM_PERFCTR_AT_PREFIX "page-read-rate",
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/perfctrs.h b/ldap/servers/slapd/back-ldbm/perfctrs.h
|
||||
index 64c79e1..a6213ec 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/perfctrs.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/perfctrs.h
|
||||
@@ -32,7 +32,6 @@ struct _performance_counters {
|
||||
uint64_t log_write_rate;
|
||||
uint64_t log_bytes_since_checkpoint;
|
||||
uint64_t cache_size_bytes;
|
||||
- uint64_t page_access_rate;
|
||||
uint64_t cache_hit;
|
||||
uint64_t cache_try;
|
||||
uint64_t page_create_rate;
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From e9514af2fed9f882a8d11d509ffb99e49a304438 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 2 May 2017 16:49:59 -0400
|
||||
Subject: [PATCH] Ticket 48681 - logconv.pl - fix sasl/bind stats
|
||||
|
||||
Description: Fixed the bind and sasl bind total counts, also adjusted the
|
||||
v3 bind count to match the sasl bind.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48681
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 770bf3a2341f1ea2e0778a6443b0f89ed77e73af)
|
||||
---
|
||||
ldap/admin/src/logconv.pl | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
|
||||
index 96639f2..c30e175 100755
|
||||
--- a/ldap/admin/src/logconv.pl
|
||||
+++ b/ldap/admin/src/logconv.pl
|
||||
@@ -2533,6 +2533,7 @@ sub parseLineNormal
|
||||
}
|
||||
if (/ BIND / && /method=sasl/i){
|
||||
$saslBindCount++;
|
||||
+ $bindCount++;
|
||||
if ($_ =~ /mech=(.*)/i ){
|
||||
my $mech = $1;
|
||||
$hashes->{saslmech}->{$mech}++;
|
||||
@@ -2550,6 +2551,8 @@ sub parseLineNormal
|
||||
if (/ RESULT err=14 tag=97 / && / SASL bind in progress/){
|
||||
# Drop the sasl bind count since this is step in the bind process
|
||||
$saslBindCount--;
|
||||
+ $bindCount--;
|
||||
+ $v3BindCount--;
|
||||
my ($conn, $op);
|
||||
if ($_ =~ /conn= *([0-9A-Z]+) +op= *([0-9\-]+)/i){
|
||||
$conn = $1;
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From cdcc387f6f1287da1edda418d746e6c2c772e5bd Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 4 May 2017 15:44:51 -0400
|
||||
Subject: [PATCH] Ticket 49241 - Update man page and usage for db2bak.pl
|
||||
|
||||
Description: The usage and man page should state thtthe backup directory
|
||||
is actually a symlink to the the server's backup directory.
|
||||
Otherwise it is misleading, and could eventaully lead to
|
||||
diskspace issues.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49241
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 0804c43991fa29ef7bd946b3e5a37844e2b87da4)
|
||||
---
|
||||
ldap/admin/src/scripts/db2bak.pl.in | 4 ++--
|
||||
man/man8/db2bak.pl.8 | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2bak.pl.in b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
index c73caa1..73d4187 100644
|
||||
--- a/ldap/admin/src/scripts/db2bak.pl.in
|
||||
+++ b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
@@ -33,8 +33,8 @@ sub usage {
|
||||
print(STDERR " -w - - Prompt for Directory Manager's password\n");
|
||||
print(STDERR " -Z serverID - Server instance identifier\n");
|
||||
print(STDERR " -j filename - Read Directory Manager's password from file\n");
|
||||
- print(STDERR " -A backupdir - Backup directory (backupdir/ID-<date_time>)\n");
|
||||
- print(STDERR " -a backupdir - Backup directory\n");
|
||||
+ print(STDERR " -A backupdir - Backup directory symlink(backupdir/ID-<date_time>)\n");
|
||||
+ print(STDERR " -a backupdir - Backup directory symlink\n");
|
||||
print(STDERR " -t dbtype - Database type (default: ldbm database)\n");
|
||||
print(STDERR " -P protocol - STARTTLS, LDAPS, LDAPI, LDAP (default: uses most secure protocol available)\n");
|
||||
print(STDERR " -h - Display usage\n");
|
||||
diff --git a/man/man8/db2bak.pl.8 b/man/man8/db2bak.pl.8
|
||||
index a752885..c51ccae 100644
|
||||
--- a/man/man8/db2bak.pl.8
|
||||
+++ b/man/man8/db2bak.pl.8
|
||||
@@ -47,7 +47,7 @@ The name of the file that contains the root DN password.
|
||||
The backend database type (default: ldbm database).
|
||||
.TP
|
||||
.B \fB\-a\fR \fIbackupdir\fR
|
||||
-The directory where the backup should be stored.
|
||||
+The directory where the backup should be stored. This directory is a symbolic link to the actual backup files located under "nsslapd-bakdir" directory that is set in the "cn=config" entry.
|
||||
.TP
|
||||
.B \fB\-A\fR \fIbackupdir\fR
|
||||
This is similar to \fB-a\fR, except that a sub-directory of \fIbackupdir\fR will be created for the backup, and the name of the sub-directory will be a timestamp of the form \fIserver-instance-date_time\fR.
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
From 0ac013079796cafb119379e40f24559187935851 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 3 May 2017 14:50:15 -0400
|
||||
Subject: [PATCH] Ticket 7662 - db2index not properly evalauating arguments
|
||||
|
||||
Description: Fix a regression where the argument count gets adjusted
|
||||
before it is checked for errors. The fix is to copy the
|
||||
number before we shift the arguments, and use that copy
|
||||
for the usage check.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/47662
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 46011e24580fcee2f438506f91b9fc119306defc)
|
||||
---
|
||||
ldap/admin/src/scripts/db2index.in | 11 ++++++-----
|
||||
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +-
|
||||
2 files changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in
|
||||
index fec082e..04183d3 100755
|
||||
--- a/ldap/admin/src/scripts/db2index.in
|
||||
+++ b/ldap/admin/src/scripts/db2index.in
|
||||
@@ -52,6 +52,7 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
+argnum=$#
|
||||
shift $(($OPTIND - 1))
|
||||
if [ $1 ]
|
||||
then
|
||||
@@ -71,18 +72,18 @@ fi
|
||||
|
||||
idxall=0
|
||||
print_usage=0
|
||||
-if [ -z $servid ] && [ $# -eq 0 ]; then
|
||||
+if [ -z $servid ] && [ $argnum -eq 0 ]; then
|
||||
idxall=1
|
||||
-elif [ "$servid" ] && [ $# -eq 2 ]; then
|
||||
+elif [ "$servid" ] && [ $argnum -eq 2 ]; then
|
||||
idxall=1
|
||||
elif [ -z $benameopt ] && [ -z $includeSuffix ]; then
|
||||
print_usage=1
|
||||
fi
|
||||
-if [ -z $servid ] && [ $# -lt 2 ]; then
|
||||
+if [ -z $servid ] && [ $argnum -lt 2 ]; then
|
||||
print_usage=1
|
||||
-elif [ -n "$servid" ] && [ $# -lt 4 ]; then
|
||||
+elif [ -n "$servid" ] && [ $argnum -lt 4 ]; then
|
||||
print_usage=1
|
||||
-elif [ -n "$servid" ] && [ $# -eq 4 ]; then
|
||||
+elif [ -n "$servid" ] && [ $argnum -eq 4 ]; then
|
||||
idxall=1
|
||||
fi
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
index f8fed7c..a0710f7 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
|
||||
@@ -3225,7 +3225,7 @@ upgradedb_core(Slapi_PBlock *pb, ldbm_instance *inst)
|
||||
run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE);
|
||||
|
||||
be = inst->inst_be;
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "upgradedb_core",
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "upgradedb_core",
|
||||
"%s: Start upgradedb.\n", inst->inst_name);
|
||||
|
||||
if (!run_from_cmdline)
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
From d3771cf05358c0230c8c77d7f7dabe9219ea7c8c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 3 May 2017 14:37:11 -0400
|
||||
Subject: [PATCH] Ticket 49075 - Adjust logging severity levels
|
||||
|
||||
Description: There are places wherre we log a severity "ERR",
|
||||
when in fact it is a benign message.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49075
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 0762e393850f54ce8462c45321b3db084bd8a0e1)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
index 36d830d..55f1887 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
@@ -118,10 +118,12 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
|
||||
|
||||
if (sane == UTIL_CACHESIZE_ERROR){
|
||||
slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: unable to determine system memory limits.");
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "Enable to determine system memory limits.\n");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set",
|
||||
+ "Enable to determine system memory limits.\n");
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
} else if (sane == UTIL_CACHESIZE_REDUCED) {
|
||||
- slapi_log_err(SLAPI_LOG_WARNING, "ldbm_instance_config_cachememsize_set", "delta +%"PRIu64" of request %"PRIu64" reduced to %"PRIu64"\n", delta_original, val, delta);
|
||||
+ slapi_log_err(SLAPI_LOG_WARNING, "ldbm_instance_config_cachememsize_set",
|
||||
+ "delta +%"PRIu64" of request %"PRIu64" reduced to %"PRIu64"\n", delta_original, val, delta);
|
||||
/*
|
||||
* This works as: value = 100
|
||||
* delta_original to inst, 20;
|
||||
@@ -133,7 +135,8 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
|
||||
}
|
||||
}
|
||||
if (inst->inst_cache.c_maxsize < MINCACHESIZE || val < MINCACHESIZE) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "force a minimal value %"PRIu64"\n", MINCACHESIZE);
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "ldbm_instance_config_cachememsize_set",
|
||||
+ "force a minimal value %"PRIu64"\n", MINCACHESIZE);
|
||||
/* This value will trigger an autotune next start up, but it should increase only */
|
||||
val = MINCACHESIZE;
|
||||
}
|
||||
@@ -1134,7 +1137,7 @@ ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry*
|
||||
return SLAPI_DSE_CALLBACK_ERROR;
|
||||
}
|
||||
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_post_delete_instance_entry_callback",
|
||||
+ slapi_log_err(SLAPI_LOG_INFO, "ldbm_instance_post_delete_instance_entry_callback",
|
||||
"Removing '%s'.\n", instance_name);
|
||||
|
||||
cache_destroy_please(&inst->inst_cache, CACHE_TYPE_ENTRY);
|
||||
@@ -1171,9 +1174,9 @@ ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry*
|
||||
dbp = PR_smprintf("%s/%s", inst_dirp, direntry->name);
|
||||
if (NULL == dbp) {
|
||||
slapi_log_err(SLAPI_LOG_ERR,
|
||||
- "ldbm_instance_post_delete_instance_entry_callback",
|
||||
- "Failed to generate db path: %s/%s\n",
|
||||
- inst_dirp, direntry->name);
|
||||
+ "ldbm_instance_post_delete_instance_entry_callback",
|
||||
+ "Failed to generate db path: %s/%s\n",
|
||||
+ inst_dirp, direntry->name);
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
|
62
SOURCES/0038-Ticket-49231-Fix-backport-issue.patch
Normal file
62
SOURCES/0038-Ticket-49231-Fix-backport-issue.patch
Normal file
|
@ -0,0 +1,62 @@
|
|||
From e0d5f86c9410bd29c0e4636d3072b24228e60128 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 5 May 2017 14:58:13 -0400
|
||||
Subject: [PATCH] Ticket 49231 - Fix backport issue
|
||||
|
||||
Description: The cherry-pick was incorrect, and caused a crash
|
||||
---
|
||||
ldap/servers/slapd/saslbind.c | 36 ++++++++++++++++++------------------
|
||||
1 file changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 6e544e6..8d23c52 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -759,26 +759,26 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
/* hard-wired mechanisms and slapi plugin registered mechanisms */
|
||||
sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
- if (pb->pb_conn == NULL) return ret;
|
||||
+ /* If we have a connection, get the provided list from SASL */
|
||||
+ if (pb->pb_conn != NULL) {
|
||||
+ sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
|
||||
|
||||
- sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
|
||||
- if (sasl_conn == NULL) return ret;
|
||||
-
|
||||
- /* sasl library mechanisms are connection dependent */
|
||||
- PR_EnterMonitor(pb->pb_conn->c_mutex);
|
||||
- if (sasl_listmech(sasl_conn,
|
||||
- NULL, /* username */
|
||||
- "", ",", "",
|
||||
- &str, NULL, NULL) == SASL_OK) {
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
- /* merge into result set */
|
||||
- dupstr = slapi_ch_strdup(str);
|
||||
- others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
- charray_merge(&ret, others, 1);
|
||||
- charray_free(others);
|
||||
- slapi_ch_free((void**)&dupstr);
|
||||
+ /* sasl library mechanisms are connection dependent */
|
||||
+ PR_EnterMonitor(pb->pb_conn->c_mutex);
|
||||
+ if (sasl_listmech(sasl_conn,
|
||||
+ NULL, /* username */
|
||||
+ "", ",", "",
|
||||
+ &str, NULL, NULL) == SASL_OK) {
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
+ /* merge into result set */
|
||||
+ dupstr = slapi_ch_strdup(str);
|
||||
+ others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
+ charray_merge(&ret, others, 1);
|
||||
+ charray_free(others);
|
||||
+ slapi_ch_free((void**)&dupstr);
|
||||
+ }
|
||||
+ PR_ExitMonitor(pb->pb_conn->c_mutex);
|
||||
}
|
||||
- PR_ExitMonitor(pb->pb_conn->c_mutex);
|
||||
|
||||
/* Get the servers "allowed" list */
|
||||
config_ret = config_get_allowed_sasl_mechs_array();
|
||||
--
|
||||
2.9.3
|
||||
|
25
SOURCES/0039-Ticket-49231-Fix-backport-issue-part2.patch
Normal file
25
SOURCES/0039-Ticket-49231-Fix-backport-issue-part2.patch
Normal file
|
@ -0,0 +1,25 @@
|
|||
From fe06dee8f346a8d8ded338bb5080c4cd3b230eef Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 5 May 2017 18:33:36 -0400
|
||||
Subject: [PATCH] Ticket 49231 - Fix backport issue (part2)
|
||||
|
||||
---
|
||||
ldap/servers/slapd/saslbind.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 8d23c52..75b83fe 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -773,7 +773,7 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
/* merge into result set */
|
||||
dupstr = slapi_ch_strdup(str);
|
||||
others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
- charray_merge(&ret, others, 1);
|
||||
+ charray_merge(&sup_ret, others, 1);
|
||||
charray_free(others);
|
||||
slapi_ch_free((void**)&dupstr);
|
||||
}
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
From e78c098543bbf64b03d1f3df98aa26184c435737 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 19 May 2017 11:18:20 -0400
|
||||
Subject: [PATCH] Ticket 48681 - logconv.pl - Fix SASL Bind stats and rework
|
||||
report format
|
||||
|
||||
Description: We were previously counting ANONYMOUS sasl bind mechanisms
|
||||
as anonymous binds. The report was also changed to make the
|
||||
binds stats clearer.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48681
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit f913252541c90ab7f3d62d74818c43ad01ff5c4e)
|
||||
---
|
||||
ldap/admin/src/logconv.pl | 52 ++++++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 40 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
|
||||
index c30e175..4932db4 100755
|
||||
--- a/ldap/admin/src/logconv.pl
|
||||
+++ b/ldap/admin/src/logconv.pl
|
||||
@@ -1099,23 +1099,23 @@ print "Max BER Size Exceeded: $maxBerSizeCount\n";
|
||||
print "\n";
|
||||
print "Binds: $bindCount\n";
|
||||
print "Unbinds: $unbindCount\n";
|
||||
+print "------------------------------";
|
||||
+print "-" x length $bindCount;
|
||||
+print "\n";
|
||||
print " - LDAP v2 Binds: $v2BindCount\n";
|
||||
print " - LDAP v3 Binds: $v3BindCount\n";
|
||||
-print " - AUTOBINDs: $autobindCount\n";
|
||||
+print " - AUTOBINDs(LDAPI): $autobindCount\n";
|
||||
print " - SSL Client Binds: $sslClientBindCount\n";
|
||||
print " - Failed SSL Client Binds: $sslClientFailedCount\n";
|
||||
print " - SASL Binds: $saslBindCount\n";
|
||||
if ($saslBindCount > 0){
|
||||
my $saslmech = $hashes->{saslmech};
|
||||
foreach my $saslb ( sort {$saslmech->{$b} <=> $saslmech->{$a} } (keys %{$saslmech}) ){
|
||||
- printf " %-4s - %s\n",$saslb, $saslmech->{$saslb};
|
||||
+ printf " - %-4s: %s\n",$saslb, $saslmech->{$saslb};
|
||||
}
|
||||
}
|
||||
-
|
||||
print " - Directory Manager Binds: $rootDNBindCount\n";
|
||||
print " - Anonymous Binds: $anonymousBindCount\n";
|
||||
-my $otherBindCount = $bindCount -($rootDNBindCount + $anonymousBindCount);
|
||||
-print " - Other Binds: $otherBindCount\n\n";
|
||||
|
||||
##########################################################################
|
||||
# Verbose Logging Section #
|
||||
@@ -1195,9 +1195,9 @@ if ($usage =~ /e/i || $verb eq "yes"){
|
||||
}
|
||||
|
||||
####################################
|
||||
-# #
|
||||
+# #
|
||||
# Print Failed Logins #
|
||||
-# #
|
||||
+# #
|
||||
####################################
|
||||
|
||||
if ($verb eq "yes" || $usage =~ /f/ ){
|
||||
@@ -2117,7 +2117,7 @@ sub parseLineNormal
|
||||
($connID) = $_ =~ /conn=(\d*)\s/;
|
||||
handleConnClose($connID);
|
||||
}
|
||||
- if (m/ BIND/ && $_ =~ /dn=\"(.*)\" method=128/i ){
|
||||
+ if (m/ BIND / && $_ =~ /dn=\"(.*)\" method=128/i ){
|
||||
my $binddn = $1;
|
||||
if($reportStats){ inc_stats('bind',$s_stats,$m_stats); }
|
||||
$bindCount++;
|
||||
@@ -2531,21 +2531,49 @@ sub parseLineNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (/ BIND / && /method=sasl/i){
|
||||
+ if (/ BIND / && $_ =~ /dn=\"(.*)\" method=sasl/i){
|
||||
+ my $binddn = $1;
|
||||
+ my ($conn, $op);
|
||||
$saslBindCount++;
|
||||
$bindCount++;
|
||||
if ($_ =~ /mech=(.*)/i ){
|
||||
my $mech = $1;
|
||||
$hashes->{saslmech}->{$mech}++;
|
||||
- my ($conn, $op);
|
||||
if ($_ =~ /conn= *([0-9A-Z]+) +op= *([0-9\-]+)/i){
|
||||
$conn = $1;
|
||||
$op = $2;
|
||||
$hashes->{saslconnop}->{$conn-$op} = $mech;
|
||||
}
|
||||
}
|
||||
- if (/ mech=ANONYMOUS/){
|
||||
- $anonymousBindCount++;
|
||||
+ if ($binddn ne ""){
|
||||
+ if($binddn eq $rootDN){ $rootDNBindCount++; }
|
||||
+ if($usage =~ /f/ || $usage =~ /u/ || $usage =~ /U/ || $usage =~ /b/ || $verb eq "yes"){
|
||||
+ $tmpp = $binddn;
|
||||
+ $tmpp =~ tr/A-Z/a-z/;
|
||||
+ $hashes->{bindlist}->{$tmpp}++;
|
||||
+ $hashes->{bind_conn_op}->{"$serverRestartCount,$conn,$op"} = $tmpp;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (/ RESULT err=/ && / tag=97 nentries=0 etime=/ && $_ =~ /dn=\"(.*)\"/i){
|
||||
+ # Check if this is a sasl bind, if see we need to add the RESULT's dn as a bind dn
|
||||
+ my $binddn = $1;
|
||||
+ my ($conn, $op);
|
||||
+ if ($_ =~ /conn= *([0-9A-Z]+) +op= *([0-9\-]+)/i){
|
||||
+ $conn = $1;
|
||||
+ $op = $2;
|
||||
+ if ($hashes->{saslconnop}->{$conn-$op} ne ""){
|
||||
+ # This was a SASL BIND - record the dn
|
||||
+ if ($binddn ne ""){
|
||||
+ if($binddn eq $rootDN){ $rootDNBindCount++; }
|
||||
+ if($usage =~ /f/ || $usage =~ /u/ || $usage =~ /U/ || $usage =~ /b/ || $verb eq "yes"){
|
||||
+ $tmpp = $binddn;
|
||||
+ $tmpp =~ tr/A-Z/a-z/;
|
||||
+ $hashes->{bindlist}->{$tmpp}++;
|
||||
+ $hashes->{bind_conn_op}->{"$serverRestartCount,$conn,$op"} = $tmpp;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (/ RESULT err=14 tag=97 / && / SASL bind in progress/){
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
From a842e43becb9312574071b1460bfa835bfecc47b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 8 May 2017 14:12:53 -0400
|
||||
Subject: [PATCH] Ticket 49157 - ds-logpipe.py crashes for non-existing users
|
||||
|
||||
Description: Remove all "raises", and gracefully exit with a message
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49157
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 94ebab36770465a50e3f61590f0f1adec2cc9224)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-logpipe.py | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-logpipe.py b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
index dc1856a..13712ea 100644
|
||||
--- a/ldap/admin/src/scripts/ds-logpipe.py
|
||||
+++ b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
@@ -146,7 +146,8 @@ def open_pipe(logfname):
|
||||
if e.errno == errno.EINTR:
|
||||
continue # open was interrupted, try again
|
||||
else: # hard error
|
||||
- raise Exception("%s [%d]" % (e.strerror, e.errno))
|
||||
+ print("%s [%d]" % (e.strerror, e.errno))
|
||||
+ sys.exit(1)
|
||||
return logf
|
||||
|
||||
def is_proc_alive(procpid):
|
||||
@@ -156,7 +157,8 @@ def is_proc_alive(procpid):
|
||||
except IOError as e:
|
||||
if e.errno != errno.ENOENT: # may not exist yet - that's ok
|
||||
# otherwise, probably permissions or other badness
|
||||
- raise Exception("could not open file %s - %s [%d]" % (procfile, e.strerror, e.errno))
|
||||
+ print("could not open file %s - %s [%d]" % (procfile, e.strerror, e.errno))
|
||||
+ sys.exit(1)
|
||||
# using /proc/pid failed, try kill
|
||||
if not retval:
|
||||
try:
|
||||
@@ -177,7 +179,8 @@ def get_pid_from_file(pidfile):
|
||||
except IOError as e:
|
||||
if e.errno != errno.ENOENT: # may not exist yet - that's ok
|
||||
# otherwise, probably permissions or other badness
|
||||
- raise Exception("Could not read pid from file %s - %s [%d]" % (pidfile, e.strerror, e.errno))
|
||||
+ print("Could not read pid from file %s - %s [%d]" % (pidfile, e.strerror, e.errno))
|
||||
+ sys.exit(1)
|
||||
if line:
|
||||
procpid = int(line)
|
||||
return procpid
|
||||
@@ -188,7 +191,8 @@ def write_pid_file(pidfile):
|
||||
pfd.write("%d\n" % os.getpid())
|
||||
pfd.close()
|
||||
except IOError as e:
|
||||
- raise Exception("Could not write pid to file %s - %s [%d]" % (pidfile, e.strerror, e.errno))
|
||||
+ print("Could not write pid to file %s - %s [%d]" % (pidfile, e.strerror, e.errno))
|
||||
+ sys.exit(1)
|
||||
|
||||
def handle_script_pidfile(scriptpidfile):
|
||||
scriptpid = get_pid_from_file(scriptpidfile)
|
||||
@@ -216,7 +220,8 @@ def read_and_process_line(logf, plgfuncs):
|
||||
if e.errno == errno.EINTR:
|
||||
continue # read was interrupted, try again
|
||||
else: # hard error
|
||||
- raise Exception("%s [%d]" % (e.strerror, e.errno))
|
||||
+ print("%s [%d]" % (e.strerror, e.errno))
|
||||
+ sys.exit(1)
|
||||
if line: # read something
|
||||
for plgfunc in plgfuncs:
|
||||
if not plgfunc(line):
|
||||
@@ -312,7 +317,8 @@ except OSError as e:
|
||||
print("Failed to create log pipe: " + str(e))
|
||||
sys.exit(1)
|
||||
else:
|
||||
- raise Exception("%s [%d]" % (e.strerror, e.errno))
|
||||
+ print("Failed to create log pipe - %s [error %d]" % (e.strerror, e.errno))
|
||||
+ sys.ext(1)
|
||||
|
||||
if debug:
|
||||
print("Listening to log pipe", logfname, "number of lines", maxlines)
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
From 834b5f7355d4233c4b9d6931ba6ec8482413bca8 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Thu, 11 May 2017 09:21:38 +0200
|
||||
Subject: [PATCH] Ticket 49249 - cos_cache is erroneously logging schema
|
||||
checking failure
|
||||
|
||||
Bug Description:
|
||||
cos is generating virtual attributes in several steps.
|
||||
One of the first step is to check that the generated attribute will
|
||||
conform the schema.
|
||||
Then additional checks (override/merge and cos scope) are performed.
|
||||
If the entry does not conform the schema, it skips the additional checks.
|
||||
In such case it logs a message stating that the virtual attribute does not
|
||||
apply.
|
||||
During slapi-log-err refactoring (https://pagure.io/389-ds-base/issue/48978)
|
||||
the logging level, in case of schema violation, was move from SLAPI_LOG_PLUGIN
|
||||
to SLAPI_LOG_ERR.
|
||||
|
||||
This change is incorrect because the potential failure to schema check is
|
||||
normal and does not imply the cos would apply to the entry (for example if
|
||||
the entry was not in the scope, the cos would also be skipped).
|
||||
|
||||
Fix Description:
|
||||
Move back the logging level from SLAPI_LOG_ERR to SLAPI_LOG_PLUGIN
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49249
|
||||
|
||||
Reviewed by: Mark Reynolds
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49249_test.py | 140 ++++++++++++++++++++++++++
|
||||
ldap/servers/plugins/cos/cos_cache.c | 2 +-
|
||||
2 files changed, 141 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dirsrvtests/tests/tickets/ticket49249_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49249_test.py b/dirsrvtests/tests/tickets/ticket49249_test.py
|
||||
new file mode 100644
|
||||
index 0000000..1dfd07e
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49249_test.py
|
||||
@@ -0,0 +1,140 @@
|
||||
+import time
|
||||
+import ldap
|
||||
+import logging
|
||||
+import pytest
|
||||
+from lib389 import DirSrv, Entry, tools, tasks
|
||||
+from lib389.tools import DirSrvTools
|
||||
+from lib389._constants import *
|
||||
+from lib389.properties import *
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+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__)
|
||||
+
|
||||
+COS_BRANCH = 'ou=cos_scope,' + DEFAULT_SUFFIX
|
||||
+COS_DEF = 'cn=cos_definition,' + COS_BRANCH
|
||||
+COS_TEMPLATE = 'cn=cos_template,' + COS_BRANCH
|
||||
+INVALID_USER_WITH_COS = 'cn=cos_user_no_mail,' + COS_BRANCH
|
||||
+VALID_USER_WITH_COS = 'cn=cos_user_with_mail,' + COS_BRANCH
|
||||
+
|
||||
+NO_COS_BRANCH = 'ou=no_cos_scope,' + DEFAULT_SUFFIX
|
||||
+INVALID_USER_WITHOUT_COS = 'cn=no_cos_user_no_mail,' + NO_COS_BRANCH
|
||||
+VALID_USER_WITHOUT_COS = 'cn=no_cos_user_with_mail,' + NO_COS_BRANCH
|
||||
+
|
||||
+def test_ticket49249(topo):
|
||||
+ """Write your testcase here...
|
||||
+
|
||||
+ Also, if you need any testcase initialization,
|
||||
+ please, write additional fixture for that(include finalizer).
|
||||
+ """
|
||||
+ # Add the branches
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((COS_BRANCH, {
|
||||
+ 'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'ou': 'cos_scope'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add cos_scope: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((NO_COS_BRANCH, {
|
||||
+ 'objectclass': 'top extensibleObject'.split(),
|
||||
+ 'ou': 'no_cos_scope'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add no_cos_scope: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((COS_TEMPLATE, {
|
||||
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
||||
+ 'cn': 'cos_template',
|
||||
+ 'cosPriority': '1',
|
||||
+ 'cn': 'cn=nsPwTemplateEntry,ou=level1,dc=example,dc=com',
|
||||
+ 'mailAlternateAddress': 'hello@world'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add cos_template: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((COS_DEF, {
|
||||
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
||||
+ 'cn': 'cos_definition',
|
||||
+ 'costemplatedn': COS_TEMPLATE,
|
||||
+ 'cosAttribute': 'mailAlternateAddress default'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add cos_definition: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ # This entry is not allowed to have mailAlternateAddress
|
||||
+ topo.standalone.add_s(Entry((INVALID_USER_WITH_COS, {
|
||||
+ 'objectclass': 'top person'.split(),
|
||||
+ 'cn': 'cos_user_no_mail',
|
||||
+ 'sn': 'cos_user_no_mail'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add cos_user_no_mail: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ # This entry is allowed to have mailAlternateAddress
|
||||
+ topo.standalone.add_s(Entry((VALID_USER_WITH_COS, {
|
||||
+ 'objectclass': 'top mailGroup'.split(),
|
||||
+ 'cn': 'cos_user_with_mail'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add cos_user_no_mail: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ # This entry is not allowed to have mailAlternateAddress
|
||||
+ topo.standalone.add_s(Entry((INVALID_USER_WITHOUT_COS, {
|
||||
+ 'objectclass': 'top person'.split(),
|
||||
+ 'cn': 'no_cos_user_no_mail',
|
||||
+ 'sn': 'no_cos_user_no_mail'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add no_cos_user_no_mail: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ # This entry is allowed to have mailAlternateAddress
|
||||
+ topo.standalone.add_s(Entry((VALID_USER_WITHOUT_COS, {
|
||||
+ 'objectclass': 'top mailGroup'.split(),
|
||||
+ 'cn': 'no_cos_user_with_mail'
|
||||
+ })))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.error('Failed to add no_cos_user_with_mail: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ try:
|
||||
+ entries = topo.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(mailAlternateAddress=*)')
|
||||
+ assert len(entries) == 1
|
||||
+ assert entries[0].hasValue('mailAlternateAddress', 'hello@world')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ log.fatal('Unable to retrieve cos_user_with_mail (only entry with mailAlternateAddress) : error %s' % (USER1_DN, e.message['desc']))
|
||||
+ assert False
|
||||
+
|
||||
+ assert not topo.standalone.ds_error_log.match(".*cos attribute mailAlternateAddress failed schema.*")
|
||||
+
|
||||
+ 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/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index 8942254..66c6c7f 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -2362,7 +2362,7 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context,
|
||||
|
||||
if(!cos_cache_schema_check(pCache, attr_index, pObjclasses))
|
||||
{
|
||||
- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_query_attr - cos attribute %s failed schema check on dn: %s\n",type,pDn);
|
||||
+ slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_cache_query_attr - cos attribute %s failed schema check on dn: %s\n",type,pDn);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
From 4182dd8bbff22f9e0e45b763a4619c0bc8dcb153 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 9 May 2017 12:31:58 -0400
|
||||
Subject: [PATCH] Ticket 49238 - AddressSanitizer: heap-use-after-free in
|
||||
libreplication
|
||||
|
||||
Bug Description:
|
||||
The bug is detected in csn pending list component, when
|
||||
accessing a csn that has already been freed.
|
||||
|
||||
The bug is mostly detectable under ASAN because under normal run
|
||||
the read access to the csn would only crash if the csn was in
|
||||
an unmapped page (that is quite difficult to acheive).
|
||||
|
||||
The bug was observed under the following conditions:
|
||||
- very slow machine
|
||||
- all instances running on the same machine
|
||||
|
||||
The patch address 2 issues
|
||||
|
||||
Issue - 1
|
||||
Under specfic circumstance (failure, like "db_deadlock" during changelog update),
|
||||
the csn was freed but still present in the pending list (fix-1).
|
||||
|
||||
Issue - 2
|
||||
Further investigations, showed an other corner case where a
|
||||
replica could be updated by several suppliers in parallel.
|
||||
In such scenario, an update (on one thread-2) with a higher csn (let csn-2)
|
||||
may be applied before an update (on another thread-1) with a smaller
|
||||
csn (let csn-1).
|
||||
csn-2 is freed when thread-2 complete but the csn-2 will remain
|
||||
in the pending list until csn-1 is commited.
|
||||
so followup of pending list may access a csn that was freed
|
||||
|
||||
Fix Description:
|
||||
Issue - 1
|
||||
The fix in repl5_plugins.c, frees the csn (thread private area)
|
||||
at the condition pending list was roll up for that csn (ruv update).
|
||||
|
||||
Issue - 2
|
||||
The fix is in two parts:
|
||||
If a supplier tries to acquire a replica while it is
|
||||
already owner of it, the replica is granted.
|
||||
|
||||
If a supplier owns a replica and is asking again for it,
|
||||
but this time the replica is not granted, the replica is release and
|
||||
the supplier disconnected.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49238
|
||||
|
||||
Reviewed by: Mark Reynolds, Ludwig Krispenz, William Brown (thanks to you all !!)
|
||||
|
||||
Platforms tested: 7.4
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5.h | 1 +
|
||||
ldap/servers/plugins/replication/repl5_plugins.c | 7 +++-
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 49 +++++++++++++++++++-----
|
||||
ldap/servers/plugins/replication/repl_extop.c | 42 ++++++++++++++++++--
|
||||
4 files changed, 86 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||
index c3bd10c..1d8989c 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||
@@ -549,6 +549,7 @@ void replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid);
|
||||
PRBool replica_get_tombstone_reap_active(const Replica *r);
|
||||
const Slapi_DN *replica_get_root(const Replica *r);
|
||||
const char *replica_get_name(const Replica *r);
|
||||
+uint64_t replica_get_locking_conn(const Replica *r);
|
||||
ReplicaId replica_get_rid (const Replica *r);
|
||||
void replica_set_rid (Replica *r, ReplicaId rid);
|
||||
PRBool replica_is_initialized (const Replica *r);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
index ebcc230..9ef06af 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
@@ -1224,7 +1224,12 @@ common_return:
|
||||
opcsn = operation_get_csn(op);
|
||||
prim_csn = get_thread_primary_csn();
|
||||
if (csn_is_equal(opcsn, prim_csn)) {
|
||||
- set_thread_primary_csn(NULL);
|
||||
+ if (return_value == 0) {
|
||||
+ /* the primary csn was succesfully committed
|
||||
+ * unset it in the thread local data
|
||||
+ */
|
||||
+ set_thread_primary_csn(NULL);
|
||||
+ }
|
||||
}
|
||||
if (repl_obj) {
|
||||
object_release (repl_obj);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index a106f8b..1bdc138 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -64,6 +64,7 @@ struct replica {
|
||||
PRBool state_update_inprogress; /* replica state is being updated */
|
||||
PRLock *agmt_lock; /* protects agreement creation, start and stop */
|
||||
char *locking_purl; /* supplier who has exclusive access */
|
||||
+ uint64_t locking_conn; /* The supplier's connection id */
|
||||
Slapi_Counter *protocol_timeout;/* protocol shutdown timeout */
|
||||
Slapi_Counter *backoff_min; /* backoff retry minimum */
|
||||
Slapi_Counter *backoff_max; /* backoff retry maximum */
|
||||
@@ -602,19 +603,32 @@ replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opi
|
||||
slapi_sdn_get_dn(r->repl_root),
|
||||
r->locking_purl ? r->locking_purl : "unknown");
|
||||
rval = PR_FALSE;
|
||||
+ if (!(r->repl_state_flags & REPLICA_TOTAL_IN_PROGRESS)) {
|
||||
+ /* inc update */
|
||||
+ if (r->locking_purl && r->locking_conn == connid) {
|
||||
+ /* This is the same supplier connection, reset the replica
|
||||
+ * purl, and return success */
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
+ "replica_get_exclusive_access - "
|
||||
+ "This is a second acquire attempt from the same replica connection "
|
||||
+ " - return success instead of busy\n");
|
||||
+ slapi_ch_free_string(&r->locking_purl);
|
||||
+ r->locking_purl = slapi_ch_strdup(locking_purl);
|
||||
+ rval = PR_TRUE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (replica_get_release_timeout(r)) {
|
||||
+ /*
|
||||
+ * Abort the current session so other replicas can acquire
|
||||
+ * this server.
|
||||
+ */
|
||||
+ r->abort_session = ABORT_SESSION;
|
||||
+ }
|
||||
+ }
|
||||
if (current_purl)
|
||||
{
|
||||
*current_purl = slapi_ch_strdup(r->locking_purl);
|
||||
}
|
||||
- if (!(r->repl_state_flags & REPLICA_TOTAL_IN_PROGRESS) &&
|
||||
- replica_get_release_timeout(r))
|
||||
- {
|
||||
- /*
|
||||
- * We are not doing a total update, so abort the current session
|
||||
- * so other replicas can acquire this server.
|
||||
- */
|
||||
- r->abort_session = ABORT_SESSION;
|
||||
- }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -642,7 +656,9 @@ replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opi
|
||||
}
|
||||
slapi_ch_free_string(&r->locking_purl);
|
||||
r->locking_purl = slapi_ch_strdup(locking_purl);
|
||||
+ r->locking_conn = connid;
|
||||
}
|
||||
+done:
|
||||
replica_unlock(r->repl_lock);
|
||||
return rval;
|
||||
}
|
||||
@@ -720,6 +736,18 @@ replica_get_name(const Replica *r) /* ONREPL - should we return copy instead? */
|
||||
return(r->repl_name);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Returns locking_conn of this replica
|
||||
+ */
|
||||
+uint64_t
|
||||
+replica_get_locking_conn(const Replica *r)
|
||||
+{
|
||||
+ uint64_t connid;
|
||||
+ replica_lock(r->repl_lock);
|
||||
+ connid = r->locking_conn;
|
||||
+ replica_unlock(r->repl_lock);
|
||||
+ return connid;
|
||||
+}
|
||||
/*
|
||||
* Returns replicaid of this replica
|
||||
*/
|
||||
@@ -2251,6 +2279,9 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
|
||||
}
|
||||
|
||||
r->tombstone_reap_stop = r->tombstone_reap_active = PR_FALSE;
|
||||
+
|
||||
+ /* No supplier holding the replica */
|
||||
+ r->locking_conn = ULONG_MAX;
|
||||
|
||||
return (_replica_check_validity (r));
|
||||
}
|
||||
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
||||
index 412caec..a39d918 100644
|
||||
--- a/ldap/servers/plugins/replication/repl_extop.c
|
||||
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
||||
@@ -1138,9 +1138,45 @@ send_response:
|
||||
*/
|
||||
if (NULL != connext && NULL != connext->replica_acquired)
|
||||
{
|
||||
- Object *r_obj = (Object*)connext->replica_acquired;
|
||||
- replica_relinquish_exclusive_access((Replica*)object_get_data (r_obj),
|
||||
- connid, opid);
|
||||
+ Replica *r = (Replica*)object_get_data ((Object*)connext->replica_acquired);
|
||||
+ uint64_t r_locking_conn;
|
||||
+
|
||||
+ /* At this point the supplier runs a Replica Agreement for
|
||||
+ * the specific replica connext->replica_acquired.
|
||||
+ * The RA does not know it holds the replica (because it is
|
||||
+ * sending this request).
|
||||
+ * The situation is confused
|
||||
+ */
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
+ "already acquired replica: replica not ready (%d) (replica=%s)\n", response, replica_get_name(r) ? replica_get_name(r) : "no name");
|
||||
+
|
||||
+ /*
|
||||
+ * On consumer side, we release the exclusive access at the
|
||||
+ * condition this is this RA that holds the replica
|
||||
+ */
|
||||
+ if (r) {
|
||||
+
|
||||
+ r_locking_conn = replica_get_locking_conn(r);
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
+ "already acquired replica: locking_conn=%d, current connid=%d\n", (int) r_locking_conn, (int) connid);
|
||||
+
|
||||
+ if ((r_locking_conn != ULONG_MAX) && (r_locking_conn == connid)) {
|
||||
+ replica_relinquish_exclusive_access(r, connid, opid);
|
||||
+ object_release((Object*) connext->replica_acquired);
|
||||
+ connext->replica_acquired = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ /*
|
||||
+ * On consumer side we should not keep a incoming connection
|
||||
+ * with replica_acquired set although the supplier is not aware of
|
||||
+ *
|
||||
+ * On the supplier, we need to close the connection so
|
||||
+ * that the RA will restart a new session in a clear state
|
||||
+ */
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
+ "already acquired replica: disconnect conn=%d\n", connid);
|
||||
+ slapi_disconnect_server(conn);
|
||||
+
|
||||
}
|
||||
/* Remove any flags that would indicate repl session in progress */
|
||||
if (NULL != connext)
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
From 18491418e661b5dc1b9ca4c6bb4adb85bfb0bf0d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 9 May 2017 16:31:52 -0400
|
||||
Subject: [PATCH] Ticket 49246 - ns-slapd crashes in role cache creation
|
||||
|
||||
Bug Description: Using a nested filter for a filtered role can
|
||||
cause a crash. This was due to the way the filter
|
||||
was being checked by the roles plugin.
|
||||
|
||||
Fix Description: Properly resurse over a filter.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49246
|
||||
|
||||
Reviewed by: firstyear & tbordaz(Thanks!!)
|
||||
|
||||
(cherry picked from commit 54e4fca35899550e0c25b25e7f7c756302d258ce)
|
||||
---
|
||||
dirsrvtests/tests/tickets/ticket49122_test.py | 61 ++++++++++++++++++---------
|
||||
ldap/servers/plugins/roles/roles_cache.c | 34 +++++++++++----
|
||||
2 files changed, 66 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/tickets/ticket49122_test.py b/dirsrvtests/tests/tickets/ticket49122_test.py
|
||||
index ff1e8d1..0945122 100644
|
||||
--- a/dirsrvtests/tests/tickets/ticket49122_test.py
|
||||
+++ b/dirsrvtests/tests/tickets/ticket49122_test.py
|
||||
@@ -2,8 +2,7 @@ import time
|
||||
import ldap
|
||||
import logging
|
||||
import pytest
|
||||
-from lib389 import DirSrv, Entry, tools, tasks
|
||||
-from lib389.tools import DirSrvTools
|
||||
+from lib389 import Entry
|
||||
from lib389._constants import *
|
||||
from lib389.properties import *
|
||||
from lib389.tasks import *
|
||||
@@ -19,6 +18,15 @@ log = logging.getLogger(__name__)
|
||||
|
||||
USER_DN = 'uid=user,' + DEFAULT_SUFFIX
|
||||
ROLE_DN = 'cn=Filtered_Role_That_Includes_Empty_Role,' + DEFAULT_SUFFIX
|
||||
+filters = ['nsrole=cn=empty,dc=example,dc=com',
|
||||
+ '(nsrole=cn=empty,dc=example,dc=com)',
|
||||
+ '(&(nsrole=cn=empty,dc=example,dc=com))',
|
||||
+ '(!(nsrole=cn=empty,dc=example,dc=com))',
|
||||
+ '(&(|(objectclass=person)(sn=app*))(userpassword=*))',
|
||||
+ '(&(|(objectclass=person)(nsrole=cn=empty,dc=example,dc=com))(userpassword=*))',
|
||||
+ '(&(|(nsrole=cn=empty,dc=example,dc=com)(sn=app*))(userpassword=*))',
|
||||
+ '(&(|(objectclass=person)(sn=app*))(nsrole=cn=empty,dc=example,dc=com))',
|
||||
+ '(&(|(&(cn=*)(objectclass=person)(nsrole=cn=empty,dc=example,dc=com)))(uid=*))']
|
||||
|
||||
|
||||
def test_ticket49122(topo):
|
||||
@@ -29,18 +37,6 @@ def test_ticket49122(topo):
|
||||
topo.standalone.plugins.enable(name=PLUGIN_ROLES)
|
||||
topo.standalone.restart()
|
||||
|
||||
- # Add invalid role
|
||||
- try:
|
||||
- topo.standalone.add_s(Entry((
|
||||
- ROLE_DN, {'objectclass': ['top', 'ldapsubentry', 'nsroledefinition',
|
||||
- 'nscomplexroledefinition', 'nsfilteredroledefinition'],
|
||||
- 'cn': 'Filtered_Role_That_Includes_Empty_Role',
|
||||
- 'nsRoleFilter': '(!(nsrole=cn=This_Is_An_Empty_Managed_NsRoleDefinition,dc=example,dc=com))',
|
||||
- 'description': 'A filtered role with filter that will crash the server'})))
|
||||
- except ldap.LDAPError as e:
|
||||
- topo.standalone.log.fatal('Failed to add filtered role: error ' + e.message['desc'])
|
||||
- assert False
|
||||
-
|
||||
# Add test user
|
||||
try:
|
||||
topo.standalone.add_s(Entry((
|
||||
@@ -51,16 +47,39 @@ def test_ticket49122(topo):
|
||||
assert False
|
||||
|
||||
if DEBUGGING:
|
||||
- # Add debugging steps(if any)...
|
||||
print("Attach gdb")
|
||||
time.sleep(20)
|
||||
|
||||
- # Search for the role
|
||||
- try:
|
||||
- topo.standalone.search_s(USER_DN, ldap.SCOPE_SUBTREE, 'objectclass=*', ['nsrole'])
|
||||
- except ldap.LDAPError as e:
|
||||
- topo.standalone.log.fatal('Search failed: error ' + str(e))
|
||||
- assert False
|
||||
+ # Loop over filters
|
||||
+ for role_filter in filters:
|
||||
+ log.info('Testing filter: ' + role_filter)
|
||||
+
|
||||
+ # Add invalid role
|
||||
+ try:
|
||||
+ topo.standalone.add_s(Entry((
|
||||
+ ROLE_DN, {'objectclass': ['top', 'ldapsubentry', 'nsroledefinition',
|
||||
+ 'nscomplexroledefinition', 'nsfilteredroledefinition'],
|
||||
+ 'cn': 'Filtered_Role_That_Includes_Empty_Role',
|
||||
+ 'nsRoleFilter': role_filter,
|
||||
+ 'description': 'A filtered role with filter that will crash the server'})))
|
||||
+ except ldap.LDAPError as e:
|
||||
+ topo.standalone.log.fatal('Failed to add filtered role: error ' + e.message['desc'])
|
||||
+ assert False
|
||||
+
|
||||
+ # Search for the role
|
||||
+ try:
|
||||
+ topo.standalone.search_s(USER_DN, ldap.SCOPE_SUBTREE, 'objectclass=*', ['nsrole'])
|
||||
+ except ldap.LDAPError as e:
|
||||
+ topo.standalone.log.fatal('Search failed: error ' + str(e))
|
||||
+ assert False
|
||||
+
|
||||
+ # Cleanup
|
||||
+ try:
|
||||
+ topo.standalone.delete_s(ROLE_DN)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ topo.standalone.log.fatal('delete failed: error ' + str(e))
|
||||
+ assert False
|
||||
+ time.sleep(1)
|
||||
|
||||
topo.standalone.log.info('Test Passed')
|
||||
|
||||
diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c
|
||||
index 4f27c4c..3697eaa 100644
|
||||
--- a/ldap/servers/plugins/roles/roles_cache.c
|
||||
+++ b/ldap/servers/plugins/roles/roles_cache.c
|
||||
@@ -1073,20 +1073,38 @@ static int roles_cache_create_role_under(roles_cache_def** roles_cache_suffix, S
|
||||
}
|
||||
|
||||
/*
|
||||
- * Check that we are not using nsrole in the filter
|
||||
+ * Check that we are not using nsrole in the filter, recurse over all the
|
||||
+ * nested filters.
|
||||
*/
|
||||
static int roles_check_filter(Slapi_Filter *filter_list)
|
||||
{
|
||||
Slapi_Filter *f;
|
||||
char *type = NULL;
|
||||
|
||||
- for ( f = slapi_filter_list_first( filter_list );
|
||||
- f != NULL;
|
||||
- f = slapi_filter_list_next( filter_list, f ) )
|
||||
- {
|
||||
- slapi_filter_get_attribute_type(f, &type);
|
||||
- if (strcasecmp(type, NSROLEATTR) == 0){
|
||||
- return -1;
|
||||
+ f = slapi_filter_list_first( filter_list );
|
||||
+ if (f == NULL){
|
||||
+ /* Single filter */
|
||||
+ if (slapi_filter_get_attribute_type(filter_list, &type) == 0){
|
||||
+ if (strcasecmp(type, NSROLEATTR) == 0){
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ for ( ; f != NULL; f = slapi_filter_list_next(filter_list, f) ){
|
||||
+ /* Complex filter */
|
||||
+ if (slapi_filter_list_first(f)) {
|
||||
+ /* Another filter list - recurse */
|
||||
+ if (roles_check_filter(f) == -1){
|
||||
+ /* Done, break out */
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Not a filter list, so check the type */
|
||||
+ if (slapi_filter_get_attribute_type(f, &type) == 0){
|
||||
+ if (strcasecmp(type, NSROLEATTR) == 0){
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
From e0cb3e9ff5337cfc4ecaa6fa5efa189b7bc16246 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 15 May 2017 11:14:43 -0400
|
||||
Subject: [PATCH 05/10] Ticket 49258 - Allow nsslapd-cache-autosize to be
|
||||
modified while the server is running
|
||||
|
||||
Bug Description: Previously you're not allowed to set nsslapd-cache-autosize, and
|
||||
nsslapd-cache-autosize-set while the server was running. The only
|
||||
way to set it was to edit the dse.ldif
|
||||
|
||||
Fix Description: Allow it to be set while the server is running. Also added value
|
||||
validation for these settigs
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49258
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit 2d07ca48f9c1232fc544361b5103d353e4791a72)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 34 ++++++++++++++++++++++++------
|
||||
1 file changed, 28 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index 401cd60..f7edd9e 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -1197,8 +1197,19 @@ static int ldbm_config_cache_autosize_set(void *arg, void *value, char *errorbuf
|
||||
{
|
||||
struct ldbminfo *li = (struct ldbminfo *)arg;
|
||||
|
||||
- if (apply)
|
||||
- li->li_cache_autosize = (int)((uintptr_t)value);
|
||||
+ if (apply) {
|
||||
+ int val = (int)((uintptr_t)value);
|
||||
+ if (val < 0 || val > 100) {
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Error: Invalid value for %s (%d). The value must be between \"0\" and \"100\"\n",
|
||||
+ CONFIG_CACHE_AUTOSIZE, val);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_cache_autosize_set",
|
||||
+ "Invalid value for %s (%d). The value must be between \"0\" and \"100\"\n",
|
||||
+ CONFIG_CACHE_AUTOSIZE, val);
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ li->li_cache_autosize = val;
|
||||
+ }
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1214,8 +1225,19 @@ static int ldbm_config_cache_autosize_split_set(void *arg, void *value, char *er
|
||||
{
|
||||
struct ldbminfo *li = (struct ldbminfo *)arg;
|
||||
|
||||
- if (apply)
|
||||
- li->li_cache_autosize_split = (int)((uintptr_t)value);
|
||||
+ if (apply) {
|
||||
+ int val = (int)((uintptr_t)value);
|
||||
+ if (val < 0 || val > 100) {
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Error: Invalid value for %s (%d). The value must be between \"0\" and \"100\"\n",
|
||||
+ CONFIG_CACHE_AUTOSIZE_SPLIT, val);
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_cache_autosize_split_set",
|
||||
+ "Invalid value for %s (%d). The value must be between \"0\" and \"100\"\n",
|
||||
+ CONFIG_CACHE_AUTOSIZE_SPLIT, val);
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ li->li_cache_autosize_split = val;
|
||||
+ }
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1582,8 +1604,8 @@ static config_info ldbm_config[] = {
|
||||
{CONFIG_DB_DEBUG_CHECKPOINTING, CONFIG_TYPE_ONOFF, "off", &ldbm_config_db_debug_checkpointing_get, &ldbm_config_db_debug_checkpointing_set, 0},
|
||||
{CONFIG_DB_HOME_DIRECTORY, CONFIG_TYPE_STRING, "", &ldbm_config_db_home_directory_get, &ldbm_config_db_home_directory_set, 0},
|
||||
{CONFIG_IMPORT_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "-1", &ldbm_config_import_cache_autosize_get, &ldbm_config_import_cache_autosize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
- {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "10", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, 0},
|
||||
- {CONFIG_CACHE_AUTOSIZE_SPLIT, CONFIG_TYPE_INT, "40", &ldbm_config_cache_autosize_split_get, &ldbm_config_cache_autosize_split_set, 0},
|
||||
+ {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "10", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
+ {CONFIG_CACHE_AUTOSIZE_SPLIT, CONFIG_TYPE_INT, "40", &ldbm_config_cache_autosize_split_get, &ldbm_config_cache_autosize_split_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_IMPORT_CACHESIZE, CONFIG_TYPE_SIZE_T, "16777216", &ldbm_config_import_cachesize_get, &ldbm_config_import_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
|
||||
{CONFIG_IDL_SWITCH, CONFIG_TYPE_STRING, "new", &ldbm_config_idl_get_idl_new, &ldbm_config_idl_set_tune, CONFIG_FLAG_ALWAYS_SHOW},
|
||||
{CONFIG_IDL_UPDATE, CONFIG_TYPE_ONOFF, "on", &ldbm_config_idl_get_update, &ldbm_config_idl_set_update, 0},
|
||||
--
|
||||
2.9.4
|
||||
|
156
SOURCES/0046-Ticket-49261-Fix-script-usage-and-man-pages.patch
Normal file
156
SOURCES/0046-Ticket-49261-Fix-script-usage-and-man-pages.patch
Normal file
|
@ -0,0 +1,156 @@
|
|||
From c0a50f26aa52bda451c5b5bce7fa2c7c2eb90fe6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 17 May 2017 16:24:50 -0400
|
||||
Subject: [PATCH] Ticket 49261 - Fix script usage and man pages
|
||||
|
||||
Description: We incorrectly said db2bak.pl and db2ldif.pl took a "-v" option,
|
||||
but they did not. Plus the usage for some of the shell scripts
|
||||
did not display "-v" option in the usage
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49261
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
---
|
||||
ldap/admin/src/scripts/db2bak.in | 3 ++-
|
||||
ldap/admin/src/scripts/db2bak.pl.in | 2 +-
|
||||
ldap/admin/src/scripts/db2index.in | 3 ++-
|
||||
ldap/admin/src/scripts/db2ldif.in | 3 ++-
|
||||
ldap/admin/src/scripts/db2ldif.pl.in | 2 +-
|
||||
ldap/admin/src/scripts/vlvindex.in | 3 ++-
|
||||
man/man8/vlvindex.8 | 6 +++++-
|
||||
7 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2bak.in b/ldap/admin/src/scripts/db2bak.in
|
||||
index e773b28..a13d2e2 100755
|
||||
--- a/ldap/admin/src/scripts/db2bak.in
|
||||
+++ b/ldap/admin/src/scripts/db2bak.in
|
||||
@@ -13,11 +13,12 @@ export SHLIB_PATH
|
||||
|
||||
usage()
|
||||
{
|
||||
- echo "Usage: db2bak [archivedir] [-Z serverID] [-q] [-h]"
|
||||
+ echo "Usage: db2bak [archivedir] [-Z serverID] [-q] [-v] [-h]"
|
||||
echo "Options:"
|
||||
echo " archivedir - Directory where the backup should be stored"
|
||||
echo " -Z serverID - Server instance identifier"
|
||||
echo " -q - Quiet mode - suppresses output"
|
||||
+ echo " -v - Display version"
|
||||
echo " -h - Display usage"
|
||||
}
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2bak.pl.in b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
index 73d4187..335285e 100644
|
||||
--- a/ldap/admin/src/scripts/db2bak.pl.in
|
||||
+++ b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
@@ -25,7 +25,7 @@ $dbtype = "ldbm database";
|
||||
$i = 0;
|
||||
|
||||
sub usage {
|
||||
- print(STDERR "Usage: db2bak.pl [-v] [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } [-a backupdir]\n");
|
||||
+ print(STDERR "Usage: db2bak.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j filename } [-a backupdir]\n");
|
||||
print(STDERR " [-t dbtype] [-P protocol] [-h]\n");
|
||||
print(STDERR "Options:\n");
|
||||
print(STDERR " -D rootdn - Directory Manager\n");
|
||||
diff --git a/ldap/admin/src/scripts/db2index.in b/ldap/admin/src/scripts/db2index.in
|
||||
index 04183d3..3fc4c2c 100755
|
||||
--- a/ldap/admin/src/scripts/db2index.in
|
||||
+++ b/ldap/admin/src/scripts/db2index.in
|
||||
@@ -14,7 +14,7 @@ export SHLIB_PATH
|
||||
usage ()
|
||||
{
|
||||
echo "Usage: db2index [-Z serverID] [-n backend | {-s includesuffix}* -t attribute[:indextypes[:matchingrules]]"
|
||||
- echo " -T vlvTag] [-h]"
|
||||
+ echo " -T vlvTag] [-v] [-h]"
|
||||
echo "Options:"
|
||||
echo " -Z serverID - Server instance identifier"
|
||||
echo " -n backend - Backend database name. Example: userRoot"
|
||||
@@ -26,6 +26,7 @@ usage ()
|
||||
echo " - matchingrules: comma separated matrules"
|
||||
echo " Example: -t foo:eq,pres"
|
||||
echo " -T vlvTag - VLV index name"
|
||||
+ echo " -v - Display version"
|
||||
echo " -h - Display usage"
|
||||
}
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2ldif.in b/ldap/admin/src/scripts/db2ldif.in
|
||||
index 08f30e4..95d2754 100755
|
||||
--- a/ldap/admin/src/scripts/db2ldif.in
|
||||
+++ b/ldap/admin/src/scripts/db2ldif.in
|
||||
@@ -16,7 +16,7 @@ cwd=`pwd`
|
||||
usage()
|
||||
{
|
||||
echo "Usage: db2ldif [-Z serverID] {-n backend_instance}* | {-s includesuffix}* [{-x excludesuffix}*] [-a outputfile]"
|
||||
- echo " [-E] [-r] [-u] [-U] [-m] [-1] [-q] [-h]"
|
||||
+ echo " [-E] [-r] [-u] [-U] [-m] [-1] [-q] [-v] [-h]"
|
||||
echo "Note: either \"-n backend\" or \"-s includesuffix\" is required."
|
||||
echo "Options:"
|
||||
echo " -Z serverID - Server instance identifier"
|
||||
@@ -31,6 +31,7 @@ usage()
|
||||
echo " -m - Do not base64 encode values"
|
||||
echo " -1 - Do not include version text"
|
||||
echo " -q - Quiet mode - suppresses output"
|
||||
+ echo " -v - Display version"
|
||||
echo " -h - Display usage"
|
||||
}
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2ldif.pl.in b/ldap/admin/src/scripts/db2ldif.pl.in
|
||||
index 179d236..0d220f0 100644
|
||||
--- a/ldap/admin/src/scripts/db2ldif.pl.in
|
||||
+++ b/ldap/admin/src/scripts/db2ldif.pl.in
|
||||
@@ -38,7 +38,7 @@ $decrypt_on_export = 0;
|
||||
$cwd = cwd();
|
||||
|
||||
sub usage {
|
||||
- print(STDERR "Usage: db2ldif.pl [-v] [-Z serverID] [-D rootdn] { -w password | -w - | -j pwfilename }\n");
|
||||
+ print(STDERR "Usage: db2ldif.pl [-Z serverID] [-D rootdn] { -w password | -w - | -j pwfilename }\n");
|
||||
print(STDERR " [-P protocol] {-n backendname}* | {-s include}* [{-x exclude}*] [-h]\n");
|
||||
print(STDERR " [-a filename] [-m] [-M] [-r] [-u] [-C] [-N] [-U] [-E] [-1] [-a filename]\n");
|
||||
print(STDERR "Options:\n");
|
||||
diff --git a/ldap/admin/src/scripts/vlvindex.in b/ldap/admin/src/scripts/vlvindex.in
|
||||
index ba2a2b3..6820de4 100755
|
||||
--- a/ldap/admin/src/scripts/vlvindex.in
|
||||
+++ b/ldap/admin/src/scripts/vlvindex.in
|
||||
@@ -13,7 +13,7 @@ export SHLIB_PATH
|
||||
|
||||
usage ()
|
||||
{
|
||||
- echo "Usage: vlvindex [-Z serverID] -n backendname | {-s includesuffix}* -T vlvTag [-d debuglevel] [-h]"
|
||||
+ echo "Usage: vlvindex [-Z serverID] -n backendname | {-s includesuffix}* -T vlvTag [-d debuglevel] [-v] [-h]"
|
||||
echo "Note: either \"-n backend\" or \"-s includesuffix\" are required."
|
||||
echo "Options:"
|
||||
echo " -Z serverID - Server instance identifier"
|
||||
@@ -21,6 +21,7 @@ usage ()
|
||||
echo " -s includessuffix - Suffix to index"
|
||||
echo " -T vlvTag - VLV index name"
|
||||
echo " -d debuglevel - Debugging level"
|
||||
+ echo " -v - Display version"
|
||||
echo " -h - Display usage"
|
||||
}
|
||||
|
||||
diff --git a/man/man8/vlvindex.8 b/man/man8/vlvindex.8
|
||||
index f3e1748..4d9497a 100644
|
||||
--- a/man/man8/vlvindex.8
|
||||
+++ b/man/man8/vlvindex.8
|
||||
@@ -18,7 +18,7 @@
|
||||
.SH NAME
|
||||
vlvindex - Directory Server script for VLV indexing
|
||||
.SH SYNOPSIS
|
||||
-vlvindex [\-Z serverID] \-n backendname | {\-s includesuffix}* \-T vlvTag [\-d debuglevel] [\-h]
|
||||
+vlvindex [\-Z serverID] \-n backendname | {\-s includesuffix}* \-T vlvTag [\-d debuglevel] [\-v] [\-h]
|
||||
.SH DESCRIPTION
|
||||
Creates virtual list view (VLV) indexes, known in the Directory Server Console as browsing indexes. VLV indexes introduce flexibility in the way search results are viewed. VLV index configuration must already exist prior to running this script. The Directory Server must be stopped before running this script.
|
||||
.SH OPTIONS
|
||||
@@ -40,6 +40,10 @@ This is the name of the vlv index entry under cn=config.
|
||||
.B \fB\-d\fR \fIDebug Level\fR
|
||||
Settings the debugging level.
|
||||
.TP
|
||||
+.B \fB\-v\fR
|
||||
+.br
|
||||
+Display the version.
|
||||
+.TP
|
||||
.B \fB\-h\fR
|
||||
.br
|
||||
Display the usage.
|
||||
--
|
||||
2.9.4
|
||||
|
46
SOURCES/0047-Ticket-48864-Fix-FreeIPA-build.patch
Normal file
46
SOURCES/0047-Ticket-48864-Fix-FreeIPA-build.patch
Normal file
|
@ -0,0 +1,46 @@
|
|||
From f007ba9e5ac0bbeee1c1d6b4e292b293629a838c Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Ashirov <vashirov@redhat.com>
|
||||
Date: Wed, 17 May 2017 22:03:54 +0200
|
||||
Subject: [PATCH] Issue 48864 - Fix FreeIPA build
|
||||
|
||||
Bug Description:
|
||||
FreeIPA build fails because of incorrect include files
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48864
|
||||
|
||||
Reviewed by: mreynolds (Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/slapi-plugin.h | 2 +-
|
||||
ldap/servers/slapd/slapi_pal.h | 2 ++
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
||||
index ec8917d..4084945 100644
|
||||
--- a/ldap/servers/slapd/slapi-plugin.h
|
||||
+++ b/ldap/servers/slapd/slapi-plugin.h
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Provides our int types and platform specific requirements. */
|
||||
-#include <slapi_pal.h>
|
||||
+#include "slapi_pal.h"
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "ldap.h"
|
||||
diff --git a/ldap/servers/slapd/slapi_pal.h b/ldap/servers/slapd/slapi_pal.h
|
||||
index cb61d84..307679d 100644
|
||||
--- a/ldap/servers/slapd/slapi_pal.h
|
||||
+++ b/ldap/servers/slapd/slapi_pal.h
|
||||
@@ -19,7 +19,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
+#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
+#endif
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
--
|
||||
2.9.4
|
||||
|
32
SOURCES/0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch
Normal file
32
SOURCES/0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
From 33dc0b3fc6de5d7a400d24a69098ec1b23917e44 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 22 May 2017 12:25:42 -0400
|
||||
Subject: [PATCH] Ticket 49157 - fix error in ds-logpipe.py
|
||||
|
||||
Description: Fix typo in ds-logpipe.py
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49157
|
||||
|
||||
Reviewed by: mreynolds(one line commit rule)
|
||||
|
||||
(cherry picked from commit 15f5f6ac42768ae0cd2040cc4169abde8187bcdf)
|
||||
---
|
||||
ldap/admin/src/scripts/ds-logpipe.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/ds-logpipe.py b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
index 13712ea..f29a9ff 100644
|
||||
--- a/ldap/admin/src/scripts/ds-logpipe.py
|
||||
+++ b/ldap/admin/src/scripts/ds-logpipe.py
|
||||
@@ -318,7 +318,7 @@ except OSError as e:
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Failed to create log pipe - %s [error %d]" % (e.strerror, e.errno))
|
||||
- sys.ext(1)
|
||||
+ sys.exit(1)
|
||||
|
||||
if debug:
|
||||
print("Listening to log pipe", logfname, "number of lines", maxlines)
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
From e52c519a8553dd8abee5740714054ebbdd59e51a Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Tue, 23 May 2017 11:03:24 +1000
|
||||
Subject: [PATCH] Ticket 49267 - autosize split of 0 results in dbcache of 0
|
||||
|
||||
Bug Description: autosize split of 0 results in a dbcache of 0. This was
|
||||
due to a missing bounds check on the value for 0. In theory this could
|
||||
still be problematic if the value was say 1% ... But hopefully we don't
|
||||
see that :)
|
||||
|
||||
Fix Description: Add the bounds check.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49267
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit 22d4865ea20acb6e6c11aed10d09241b09bb711c)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/start.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/start.c b/ldap/servers/slapd/back-ldbm/start.c
|
||||
index a207bd8..1834a19 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/start.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/start.c
|
||||
@@ -101,7 +101,11 @@ ldbm_back_start_autotune(struct ldbminfo *li) {
|
||||
/* This doesn't control the availability of the feature, so we can take the
|
||||
* default from ldbm_config.c
|
||||
*/
|
||||
- autosize_db_percentage_split = li->li_cache_autosize_split;
|
||||
+ if (li->li_cache_autosize_split == 0) {
|
||||
+ autosize_db_percentage_split = 40;
|
||||
+ } else {
|
||||
+ autosize_db_percentage_split = li->li_cache_autosize_split;
|
||||
+ }
|
||||
|
||||
|
||||
/* Check the values are sane. */
|
||||
@@ -131,10 +135,18 @@ ldbm_back_start_autotune(struct ldbminfo *li) {
|
||||
db_size = (autosize_db_percentage_split * zone_size) / 100;
|
||||
|
||||
/* Cap the DB size at 512MB, as this doesn't help perf much more (lkrispen's advice) */
|
||||
+ /* NOTE: Do we need a minimum DB size? */
|
||||
if (db_size > (512 * MEGABYTE)) {
|
||||
db_size = (512 * MEGABYTE);
|
||||
}
|
||||
|
||||
+ /* NOTE: Because of how we workout entry_size, even if
|
||||
+ * have autosize split to say ... 90% for dbcache, because
|
||||
+ * we cap db_size, we use zone_size - db_size, meaning that entry
|
||||
+ * cache still gets the remaining memory *even* though we didn't use it all.
|
||||
+ * If we didn't do this, entry_cache would only get 10% of of the avail, even
|
||||
+ * if db_size was caped at say 5% down from 90.
|
||||
+ */
|
||||
if (backend_count > 0 ) {
|
||||
/* Number of entry cache pages per backend. */
|
||||
entry_size = (zone_size - db_size) / backend_count;
|
||||
--
|
||||
2.9.4
|
||||
|
114
SOURCES/0050-Ticket-49231-force-EXTERNAL-always.patch
Normal file
114
SOURCES/0050-Ticket-49231-force-EXTERNAL-always.patch
Normal file
|
@ -0,0 +1,114 @@
|
|||
From d2648bbddbf087c4e3803a89cb67541a50682eae Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 15 May 2017 09:04:45 +1000
|
||||
Subject: [PATCH] Ticket 49231 - force EXTERNAL always
|
||||
|
||||
Bug Description: Because of how our sasl code works, EXTERNAL bypasses
|
||||
a number of checks so is always available.
|
||||
|
||||
Fix Description: Force EXTERNAL to the present mech list, regardless
|
||||
of the whitelist.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49231
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynosd (Thanks!)
|
||||
|
||||
(cherry picked from commit e6e0db35842fc6612134cff5a08c4968230d1b2f)
|
||||
---
|
||||
dirsrvtests/tests/suites/sasl/allowed_mechs.py | 13 +++++++++++--
|
||||
ldap/servers/slapd/charray.c | 14 ++++++++++++++
|
||||
ldap/servers/slapd/saslbind.c | 9 +++++++++
|
||||
ldap/servers/slapd/slapi-private.h | 2 ++
|
||||
4 files changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/allowed_mechs.py b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
index a3e385e..7958db4 100644
|
||||
--- a/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
+++ b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
@@ -25,12 +25,21 @@ def test_sasl_allowed_mechs(topology_st):
|
||||
assert('EXTERNAL' in orig_mechs)
|
||||
|
||||
# Now edit the supported mechs. CHeck them again.
|
||||
- standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'EXTERNAL, PLAIN')
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN')
|
||||
|
||||
limit_mechs = standalone.rootdse.supported_sasl()
|
||||
- print(limit_mechs)
|
||||
assert('PLAIN' in limit_mechs)
|
||||
+ # Should always be in the allowed list, even if not set.
|
||||
assert('EXTERNAL' in limit_mechs)
|
||||
+ # Should not be there!
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, EXTERNAL')
|
||||
+
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ # Should not be there!
|
||||
assert('GSSAPI' not in limit_mechs)
|
||||
|
||||
# Do a config reset
|
||||
diff --git a/ldap/servers/slapd/charray.c b/ldap/servers/slapd/charray.c
|
||||
index 6b89714..9056f16 100644
|
||||
--- a/ldap/servers/slapd/charray.c
|
||||
+++ b/ldap/servers/slapd/charray.c
|
||||
@@ -272,6 +272,20 @@ charray_utf8_inlist(
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Assert that some str s is in the charray, or add it.
|
||||
+ */
|
||||
+void
|
||||
+charray_assert_present(char ***a, char *s)
|
||||
+{
|
||||
+ int result = charray_utf8_inlist(*a, s);
|
||||
+ /* Not in the list */
|
||||
+ if (result == 0) {
|
||||
+ char *sdup = slapi_ch_strdup(s);
|
||||
+ slapi_ch_array_add_ext(a, sdup);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int slapi_ch_array_utf8_inlist(char **a, char *s)
|
||||
{
|
||||
return charray_utf8_inlist(a,s);
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 75b83fe..dd0c4fb 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -794,6 +794,15 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
ret = sup_ret;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * https://pagure.io/389-ds-base/issue/49231
|
||||
+ * Because of the way that SASL mechs are managed in bind.c and saslbind.c
|
||||
+ * even if EXTERNAL was *not* in the list of allowed mechs, it was allowed
|
||||
+ * in the bind process because it bypasses lots of our checking. As a result
|
||||
+ * we have to always present it.
|
||||
+ */
|
||||
+ charray_assert_present(&ret, "EXTERNAL");
|
||||
+
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "<=\n");
|
||||
|
||||
return ret;
|
||||
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
||||
index 3f732e8..0836d66 100644
|
||||
--- a/ldap/servers/slapd/slapi-private.h
|
||||
+++ b/ldap/servers/slapd/slapi-private.h
|
||||
@@ -834,6 +834,8 @@ void charray_subtract( char **a, char **b, char ***c );
|
||||
char **charray_intersection(char **a, char **b);
|
||||
int charray_get_index(char **array, char *s);
|
||||
int charray_normdn_add(char ***chararray, char *dn, char *errstr);
|
||||
+void charray_assert_present(char ***a, char *s);
|
||||
+
|
||||
|
||||
/******************************************************************************
|
||||
* value array routines.
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From bbc63ef4dab6c275b1d8b8fe6439483309781401 Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Fri, 12 May 2017 10:09:32 +1000
|
||||
Subject: [PATCH] Ticket 48538 - Failed to delete old semaphore
|
||||
|
||||
Bug Description: I misunderstood the sem_unlink call, and logged
|
||||
the wrong filepath.
|
||||
|
||||
Fix Description: Fix the file path of the semaphore.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/48538
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (Thanks!)
|
||||
|
||||
(cherry picked from commit b81c8ba38c29e15e13b0dd0bf6f5d3c773d31b20)
|
||||
---
|
||||
ldap/servers/slapd/snmp_collator.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
|
||||
index 21043d9..2deab91 100644
|
||||
--- a/ldap/servers/slapd/snmp_collator.c
|
||||
+++ b/ldap/servers/slapd/snmp_collator.c
|
||||
@@ -458,23 +458,23 @@ snmp_collator_create_semaphore(void)
|
||||
* around. Recreate it since we don't know what state it is in. */
|
||||
if (sem_unlink(stats_sem_name) != 0) {
|
||||
slapi_log_err(SLAPI_LOG_EMERG, "snmp_collator_create_semaphore",
|
||||
- "Failed to delete old semaphore for stats file (%s). "
|
||||
- "Error %d (%s).\n", stats_sem_name, errno, slapd_system_strerror(errno) );
|
||||
+ "Failed to delete old semaphore for stats file (/dev/shm/sem.%s). "
|
||||
+ "Error %d (%s).\n", stats_sem_name + 1, errno, slapd_system_strerror(errno) );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((stats_sem = sem_open(stats_sem_name, O_CREAT | O_EXCL, SLAPD_DEFAULT_FILE_MODE, 1)) == SEM_FAILED) {
|
||||
/* No dice */
|
||||
slapi_log_err(SLAPI_LOG_EMERG, "snmp_collator_create_semaphore",
|
||||
- "Failed to create semaphore for stats file (%s). Error %d (%s).\n",
|
||||
- stats_sem_name, errno, slapd_system_strerror(errno) );
|
||||
+ "Failed to create semaphore for stats file (/dev/shm/sem.%s). Error %d (%s).\n",
|
||||
+ stats_sem_name + 1, errno, slapd_system_strerror(errno) );
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
/* Some other problem occurred creating the semaphore. */
|
||||
slapi_log_err(SLAPI_LOG_EMERG, "snmp_collator_create_semaphore",
|
||||
- "Failed to create semaphore for stats file (%s). Error %d.(%s)\n",
|
||||
- stats_sem_name, errno, slapd_system_strerror(errno) );
|
||||
+ "Failed to create semaphore for stats file (/dev/shm/sem.%s). Error %d.(%s)\n",
|
||||
+ stats_sem_name + 1, errno, slapd_system_strerror(errno) );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
From 0f04c8e7c1219940baf0ae9c1bcb2464ddf079df Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 16 May 2017 13:19:43 -0400
|
||||
Subject: [PATCH] Ticket 49257 - Reject nsslapd-cachememsize &
|
||||
nsslapd-cachesize when nsslapd-cache-autosize is set
|
||||
|
||||
Description: We need to also reject entry cache changes when cache autosizing is being used.
|
||||
|
||||
I also found out that we were not registering the ldbm instance callbacks at startup.
|
||||
So all those functions were only used when creating an instance, and not after it was
|
||||
started.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49257
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/instance.c | 19 +++++++++----
|
||||
.../servers/slapd/back-ldbm/ldbm_instance_config.c | 32 ++++++++++++++++++++--
|
||||
ldap/servers/slapd/back-ldbm/start.c | 2 +-
|
||||
3 files changed, 44 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
index f79d048..8b38644 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/instance.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
@@ -302,12 +302,19 @@ ldbm_instance_startall(struct ldbminfo *li)
|
||||
inst = (ldbm_instance *) object_get_data(inst_obj);
|
||||
ldbm_instance_set_flags(inst);
|
||||
rc1 = ldbm_instance_start(inst->inst_be);
|
||||
- if (rc1 != 0) {
|
||||
- rc = rc1;
|
||||
- } else {
|
||||
- vlv_init(inst);
|
||||
- slapi_mtn_be_started(inst->inst_be);
|
||||
- }
|
||||
+ if (rc1 != 0) {
|
||||
+ rc = rc1;
|
||||
+ } else {
|
||||
+ if(ldbm_instance_config_load_dse_info(inst) != 0){
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_startall",
|
||||
+ "Loading database instance configuration failed for (%s)\n",
|
||||
+ inst->inst_name);
|
||||
+ rc = -1;
|
||||
+ } else {
|
||||
+ vlv_init(inst);
|
||||
+ slapi_mtn_be_started(inst->inst_be);
|
||||
+ }
|
||||
+ }
|
||||
inst_obj = objset_next_obj(li->li_instance_set, inst_obj);
|
||||
}
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
index 55f1887..49a6cac 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
@@ -72,6 +72,18 @@ ldbm_instance_config_cachesize_set(void *arg, void *value, char *errorbuf, int p
|
||||
/* Do whatever we can to make sure the data is ok. */
|
||||
|
||||
if (apply) {
|
||||
+ if (CONFIG_PHASE_RUNNING == phase) {
|
||||
+ if (val > 0 && inst->inst_li->li_cache_autosize) {
|
||||
+ /* We are auto-tuning the cache, so this change would be overwritten - return an error */
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Error: \"nsslapd-cachesize\" can not be updated while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachesize_set",
|
||||
+ "\"nsslapd-cachesize\" can not be set while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".\n");
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ }
|
||||
cache_set_max_entries(&(inst->inst_cache), val);
|
||||
}
|
||||
|
||||
@@ -87,7 +99,11 @@ ldbm_instance_config_cachememsize_get(void *arg)
|
||||
}
|
||||
|
||||
static int
|
||||
-ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, int phase, int apply)
|
||||
+ldbm_instance_config_cachememsize_set(void *arg,
|
||||
+ void *value,
|
||||
+ char *errorbuf,
|
||||
+ int phase,
|
||||
+ int apply)
|
||||
{
|
||||
ldbm_instance *inst = (ldbm_instance *) arg;
|
||||
int retval = LDAP_SUCCESS;
|
||||
@@ -107,6 +123,18 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
|
||||
*/
|
||||
|
||||
if (apply) {
|
||||
+ if (CONFIG_PHASE_RUNNING == phase) {
|
||||
+ if (val > 0 && inst->inst_li->li_cache_autosize) {
|
||||
+ /* We are auto-tuning the cache, so this change would be overwritten - return an error */
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Error: \"nsslapd-cachememsize\" can not be updated while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set",
|
||||
+ "\"nsslapd-cachememsize\" can not be set while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".\n");
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
+ }
|
||||
if (val > inst->inst_cache.c_maxsize) {
|
||||
delta = val - inst->inst_cache.c_maxsize;
|
||||
delta_original = delta;
|
||||
@@ -825,7 +853,7 @@ ldbm_instance_modify_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryB
|
||||
continue;
|
||||
}
|
||||
|
||||
- /* This assumes there is only one bval for this mod. */
|
||||
+ /* This assumes there is only one bval for this mod. */
|
||||
if (mods[i]->mod_bvalues == NULL) {
|
||||
/* This avoids the null pointer deref.
|
||||
* In ldbm_config.c ldbm_config_set, it checks for the NULL.
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/start.c b/ldap/servers/slapd/back-ldbm/start.c
|
||||
index 1834a19..d4e8bb8 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/start.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/start.c
|
||||
@@ -169,7 +169,7 @@ ldbm_back_start_autotune(struct ldbminfo *li) {
|
||||
}
|
||||
|
||||
slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "found %luk physical memory\n", mi->system_total_bytes / 1024);
|
||||
- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "found %luk avaliable\n", mi->system_available_bytes / 1024);
|
||||
+ slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "found %luk available\n", mi->system_available_bytes / 1024);
|
||||
|
||||
/* We've now calculated the autotuning values. Do we need to apply it?
|
||||
* we use the logic of "if size is 0, or autosize is > 0. This way three
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 550d30d3aa27cd69057604e1ee7d5ca43711d718 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 15 May 2017 13:30:22 -0400
|
||||
Subject: [PATCH] Ticket 49257 - Reject dbcachesize updates while auto cache
|
||||
sizing is enabled
|
||||
|
||||
Description: We should reject updates to nsslapd-dbcachesize while auto cache sizing
|
||||
is in effect. This is because at startup we would overwrite the
|
||||
manually set dbcache size anyway. It would never take effect, so it
|
||||
should be rejected.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49257
|
||||
|
||||
Reviewed by: tbordaz & firstyear(Thanks!!)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
index f7edd9e..6c1dda0 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
|
||||
@@ -420,7 +420,7 @@ static int ldbm_config_dbcachesize_set(void *arg, void *value, char *errorbuf, i
|
||||
/* Stop the user configuring a stupidly small cache */
|
||||
/* min: 8KB (page size) * def thrd cnts (threadnumber==20). */
|
||||
#define DBDEFMINSIZ 500000
|
||||
- /* We allow a value of 0, because the autotuting in start.c will
|
||||
+ /* We allow a value of 0, because the autotuning in start.c will
|
||||
* register that, and trigger the recalculation of the dbcachesize as
|
||||
* needed on the next start up.
|
||||
*/
|
||||
@@ -443,7 +443,18 @@ static int ldbm_config_dbcachesize_set(void *arg, void *value, char *errorbuf, i
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
}
|
||||
+
|
||||
if (CONFIG_PHASE_RUNNING == phase) {
|
||||
+ if (val > 0 && li->li_cache_autosize) {
|
||||
+ /* We are auto-tuning the cache, so this change would be overwritten - return an error */
|
||||
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||
+ "Error: \"nsslapd-dbcachesize\" can not be updated while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_dbcachesize_set",
|
||||
+ "\"nsslapd-dbcachesize\" can not be set while \"nsslapd-cache-autosize\" is set "
|
||||
+ "in \"cn=config,cn=ldbm database,cn=plugins,cn=config\".\n");
|
||||
+ return LDAP_UNWILLING_TO_PERFORM;
|
||||
+ }
|
||||
li->li_new_dbcachesize = val;
|
||||
if (val == 0) {
|
||||
slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_config_dbcachesize_set", "cache size reset to 0, will be autosized on next startup.\n");
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
From db98cb29158741cc960f1e1a2df3d4214f5bd36e Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 6 Jun 2017 10:50:19 -0400
|
||||
Subject: [PATCH] Ticket 49184 - adjust logging level in MO plugin
|
||||
|
||||
Description: Change logging level for benign message
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49184
|
||||
|
||||
Reviewed by: mreynolds(one line commit ruile)
|
||||
---
|
||||
ldap/servers/plugins/memberof/memberof.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index 5cd2c01..9bbe13c 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -3396,7 +3396,7 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
/* This is quite unexpected, after a call to memberof_get_groups
|
||||
* ndn ancestors should be in the cache
|
||||
*/
|
||||
- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: Weird, %s is not in the cache\n", ndn);
|
||||
+ slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: Weird, %s is not in the cache\n", ndn);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
From 6935bd0821395051c0483b0ee393d2d4567f6f0c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 24 May 2017 12:15:20 -0400
|
||||
Subject: [PATCH] Ticket 49241 - add symblic link location to db2bak.pl output
|
||||
|
||||
Description: If a symbolic link is used for the script's backup
|
||||
location then add info to the output.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49241
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
|
||||
(cherry picked from commit 95a7f23262076d90fdc8a9ec76e131e9e4c09bcc)
|
||||
---
|
||||
ldap/admin/src/scripts/db2bak.pl.in | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/admin/src/scripts/db2bak.pl.in b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
index 335285e..352a01e 100644
|
||||
--- a/ldap/admin/src/scripts/db2bak.pl.in
|
||||
+++ b/ldap/admin/src/scripts/db2bak.pl.in
|
||||
@@ -105,7 +105,12 @@ if ($archivedir eq "") {
|
||||
} else {
|
||||
$symname = $archivedir;
|
||||
}
|
||||
- print("Back up directory: $archivedir\n");
|
||||
+ if ($symname eq "") {
|
||||
+ print("Back up directory: $archivedir\n");
|
||||
+ } else {
|
||||
+ print("Back up directory: $archivedir -> $mybakdir/$archivebase\n");
|
||||
+ }
|
||||
+
|
||||
# If an archive dir is specified, create it as a symlink pointing
|
||||
# to the default backup dir not to violate the selinux policy.
|
||||
$archivedir = "${mybakdir}/${archivebase}";
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
From 0fc3c803c34311eb05c5c7a7e710c8591b592649 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Thu, 27 Jul 2017 18:10:05 +0200
|
||||
Subject: [PATCH] Ticket 49313 - Change the retrochangelog default cache size
|
||||
|
||||
Bug Description:
|
||||
Default retroCL backend entry cache size is 2Mb.
|
||||
It has been reported in many deployments that DB corruption could
|
||||
be prevented by increasing entry cache to 200Mb.
|
||||
There is no identified reproducible steps to debug this DB corruption.
|
||||
So to prevent this problem we are increasing the entry cache
|
||||
|
||||
Fix Description:
|
||||
Set default cn=changelog cache to 200Mb (based on production cases)
|
||||
An other option would be to set a maximum number of entries but
|
||||
as we do not know if it works to prevent DB corruption, let's prefere
|
||||
entry cache size
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49313
|
||||
|
||||
Reviewed by: William Brown
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/plugins/retrocl/retrocl.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h
|
||||
index 6963d4b..eef1a17 100644
|
||||
--- a/ldap/servers/plugins/retrocl/retrocl.h
|
||||
+++ b/ldap/servers/plugins/retrocl/retrocl.h
|
||||
@@ -58,7 +58,7 @@ typedef struct _cnumRet {
|
||||
#else
|
||||
#define RETROCL_DLL_DEFAULT_THREAD_STACKSIZE 131072L
|
||||
#endif
|
||||
-#define RETROCL_BE_CACHEMEMSIZE "2097152"
|
||||
+#define RETROCL_BE_CACHEMEMSIZE "209715200"
|
||||
#define RETROCL_BE_CACHESIZE "-1"
|
||||
#define RETROCL_PLUGIN_NAME "DSRetroclPlugin"
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,795 @@
|
|||
From 6b5aa0e288f1ea5553d4dd5d220d4e5daf50a247 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 31 Jul 2017 14:45:50 -0400
|
||||
Subject: [PATCH] Ticket 49287 - v3 extend csnpl handling to multiple backends
|
||||
|
||||
The csn pending list mechanism failed if internal operation affected multiple backends
|
||||
|
||||
This fix is an extension to the fix in ticket 49008, the thread local data now also contains
|
||||
a list of all affected replicas.
|
||||
|
||||
http://www.port389.org/docs/389ds/design/csn-pending-lists-and-ruv-update.html
|
||||
|
||||
Reviewed by: William, Thierry - thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/csnpl.c | 85 ++++++++--
|
||||
ldap/servers/plugins/replication/csnpl.h | 8 +-
|
||||
ldap/servers/plugins/replication/repl5.h | 22 ++-
|
||||
ldap/servers/plugins/replication/repl5_init.c | 48 +++++-
|
||||
ldap/servers/plugins/replication/repl5_plugins.c | 16 +-
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 18 ++-
|
||||
ldap/servers/plugins/replication/repl5_ruv.c | 191 ++++++++++++++---------
|
||||
ldap/servers/plugins/replication/repl5_ruv.h | 6 +-
|
||||
ldap/servers/slapd/slapi-private.h | 2 +-
|
||||
9 files changed, 283 insertions(+), 113 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/csnpl.c b/ldap/servers/plugins/replication/csnpl.c
|
||||
index 4a0f5f5..12a0bb8 100644
|
||||
--- a/ldap/servers/plugins/replication/csnpl.c
|
||||
+++ b/ldap/servers/plugins/replication/csnpl.c
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "csnpl.h"
|
||||
#include "llist.h"
|
||||
-#include "repl_shared.h"
|
||||
|
||||
struct csnpl
|
||||
{
|
||||
@@ -22,13 +21,17 @@ struct csnpl
|
||||
Slapi_RWLock* csnLock; /* lock to serialize access to PL */
|
||||
};
|
||||
|
||||
+
|
||||
typedef struct _csnpldata
|
||||
{
|
||||
PRBool committed; /* True if CSN committed */
|
||||
CSN *csn; /* The actual CSN */
|
||||
+ Replica * prim_replica; /* The replica where the prom csn was generated */
|
||||
const CSN *prim_csn; /* The primary CSN of an operation consising of multiple sub ops*/
|
||||
} csnpldata;
|
||||
|
||||
+static PRBool csn_primary_or_nested(csnpldata *csn_data, const CSNPL_CTX *csn_ctx);
|
||||
+
|
||||
/* forward declarations */
|
||||
#ifdef DEBUG
|
||||
static void _csnplDumpContentNoLock(CSNPL *csnpl, const char *caller);
|
||||
@@ -104,7 +107,7 @@ void csnplFree (CSNPL **csnpl)
|
||||
* 1 if the csn has already been seen
|
||||
* -1 for any other kind of errors
|
||||
*/
|
||||
-int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn)
|
||||
+int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSNPL_CTX *prim_csn)
|
||||
{
|
||||
int rc;
|
||||
csnpldata *csnplnode;
|
||||
@@ -129,10 +132,13 @@ int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- csnplnode = (csnpldata *)slapi_ch_malloc(sizeof(csnpldata));
|
||||
+ csnplnode = (csnpldata *)slapi_ch_calloc(1, sizeof(csnpldata));
|
||||
csnplnode->committed = PR_FALSE;
|
||||
csnplnode->csn = csn_dup(csn);
|
||||
- csnplnode->prim_csn = prim_csn;
|
||||
+ if (prim_csn) {
|
||||
+ csnplnode->prim_csn = prim_csn->prim_csn;
|
||||
+ csnplnode->prim_replica = prim_csn->prim_repl;
|
||||
+ }
|
||||
csn_as_string(csn, PR_FALSE, csn_str);
|
||||
rc = llistInsertTail (csnpl->csnList, csn_str, csnplnode);
|
||||
|
||||
@@ -187,8 +193,58 @@ int csnplRemove (CSNPL *csnpl, const CSN *csn)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+PRBool csn_primary(Replica *replica, const CSN *csn, const CSNPL_CTX *csn_ctx)
|
||||
+{
|
||||
+ if (csn_ctx == NULL)
|
||||
+ return PR_FALSE;
|
||||
+
|
||||
+ if (replica != csn_ctx->prim_repl) {
|
||||
+ /* The CSNs are not from the same replication topology
|
||||
+ * so even if the csn values are equal they are not related
|
||||
+ * to the same operation
|
||||
+ */
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Here the two CSNs belong to the same replication topology */
|
||||
+
|
||||
+ /* check if the CSN identifies the primary update */
|
||||
+ if (csn_is_equal(csn, csn_ctx->prim_csn)) {
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+
|
||||
+ return PR_FALSE;
|
||||
+}
|
||||
+
|
||||
+static PRBool csn_primary_or_nested(csnpldata *csn_data, const CSNPL_CTX *csn_ctx)
|
||||
+{
|
||||
+ if ((csn_data == NULL) || (csn_ctx == NULL))
|
||||
+ return PR_FALSE;
|
||||
+
|
||||
+ if (csn_data->prim_replica != csn_ctx->prim_repl) {
|
||||
+ /* The CSNs are not from the same replication topology
|
||||
+ * so even if the csn values are equal they are not related
|
||||
+ * to the same operation
|
||||
+ */
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Here the two CSNs belong to the same replication topology */
|
||||
+
|
||||
+ /* First check if the CSN identifies the primary update */
|
||||
+ if (csn_is_equal(csn_data->csn, csn_ctx->prim_csn)) {
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+
|
||||
+ /* Second check if the CSN identifies a nested update */
|
||||
+ if (csn_is_equal(csn_data->prim_csn, csn_ctx->prim_csn)) {
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+
|
||||
+ return PR_FALSE;
|
||||
+}
|
||||
|
||||
-int csnplRemoveAll (CSNPL *csnpl, const CSN *csn)
|
||||
+int csnplRemoveAll (CSNPL *csnpl, const CSNPL_CTX *csn_ctx)
|
||||
{
|
||||
csnpldata *data;
|
||||
void *iterator;
|
||||
@@ -197,8 +253,7 @@ int csnplRemoveAll (CSNPL *csnpl, const CSN *csn)
|
||||
data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
|
||||
while (NULL != data)
|
||||
{
|
||||
- if (csn_is_equal(data->csn, csn) ||
|
||||
- csn_is_equal(data->prim_csn, csn)) {
|
||||
+ if (csn_primary_or_nested(data, csn_ctx)) {
|
||||
csnpldata_free(&data);
|
||||
data = (csnpldata *)llistRemoveCurrentAndGetNext(csnpl->csnList, &iterator);
|
||||
} else {
|
||||
@@ -213,13 +268,13 @@ int csnplRemoveAll (CSNPL *csnpl, const CSN *csn)
|
||||
}
|
||||
|
||||
|
||||
-int csnplCommitAll (CSNPL *csnpl, const CSN *csn)
|
||||
+int csnplCommitAll (CSNPL *csnpl, const CSNPL_CTX *csn_ctx)
|
||||
{
|
||||
csnpldata *data;
|
||||
void *iterator;
|
||||
char csn_str[CSN_STRSIZE];
|
||||
|
||||
- csn_as_string(csn, PR_FALSE, csn_str);
|
||||
+ csn_as_string(csn_ctx->prim_csn, PR_FALSE, csn_str);
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"csnplCommitALL: committing all csns for csn %s\n", csn_str);
|
||||
slapi_rwlock_wrlock (csnpl->csnLock);
|
||||
@@ -229,8 +284,7 @@ int csnplCommitAll (CSNPL *csnpl, const CSN *csn)
|
||||
csn_as_string(data->csn, PR_FALSE, csn_str);
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"csnplCommitALL: processing data csn %s\n", csn_str);
|
||||
- if (csn_is_equal(data->csn, csn) ||
|
||||
- csn_is_equal(data->prim_csn, csn)) {
|
||||
+ if (csn_primary_or_nested(data, csn_ctx)) {
|
||||
data->committed = PR_TRUE;
|
||||
}
|
||||
data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
|
||||
@@ -395,7 +449,12 @@ static void _csnplDumpContentNoLock(CSNPL *csnpl, const char *caller)
|
||||
|
||||
/* wrapper around csn_free, to satisfy NSPR thread context API */
|
||||
void
|
||||
-csnplFreeCSN (void *arg)
|
||||
+csnplFreeCSNPL_CTX (void *arg)
|
||||
{
|
||||
- csn_free((CSN **)&arg);
|
||||
+ CSNPL_CTX *csnpl_ctx = (CSNPL_CTX *)arg;
|
||||
+ csn_free(&csnpl_ctx->prim_csn);
|
||||
+ if (csnpl_ctx->sec_repl) {
|
||||
+ slapi_ch_free((void **)&csnpl_ctx->sec_repl);
|
||||
+ }
|
||||
+ slapi_ch_free((void **)&csnpl_ctx);
|
||||
}
|
||||
diff --git a/ldap/servers/plugins/replication/csnpl.h b/ldap/servers/plugins/replication/csnpl.h
|
||||
index 594c8f2..1036c62 100644
|
||||
--- a/ldap/servers/plugins/replication/csnpl.h
|
||||
+++ b/ldap/servers/plugins/replication/csnpl.h
|
||||
@@ -17,15 +17,17 @@
|
||||
#define CSNPL_H
|
||||
|
||||
#include "slapi-private.h"
|
||||
+#include "repl5.h"
|
||||
|
||||
typedef struct csnpl CSNPL;
|
||||
|
||||
CSNPL* csnplNew(void);
|
||||
void csnplFree (CSNPL **csnpl);
|
||||
-int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn);
|
||||
+int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSNPL_CTX *prim_csn);
|
||||
int csnplRemove (CSNPL *csnpl, const CSN *csn);
|
||||
-int csnplRemoveAll (CSNPL *csnpl, const CSN *csn);
|
||||
-int csnplCommitAll (CSNPL *csnpl, const CSN *csn);
|
||||
+int csnplRemoveAll (CSNPL *csnpl, const CSNPL_CTX *csn_ctx);
|
||||
+int csnplCommitAll (CSNPL *csnpl, const CSNPL_CTX *csn_ctx);
|
||||
+PRBool csn_primary(Replica *replica, const CSN *csn, const CSNPL_CTX *csn_ctx);
|
||||
CSN* csnplGetMinCSN (CSNPL *csnpl, PRBool *committed);
|
||||
int csnplCommit (CSNPL *csnpl, const CSN *csn);
|
||||
CSN *csnplRollUp(CSNPL *csnpl, CSN ** first);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||
index 1d8989c..718f64e 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||
@@ -228,12 +228,27 @@ int multimaster_be_betxnpostop_delete (Slapi_PBlock *pb);
|
||||
int multimaster_be_betxnpostop_add (Slapi_PBlock *pb);
|
||||
int multimaster_be_betxnpostop_modify (Slapi_PBlock *pb);
|
||||
|
||||
+/* In repl5_replica.c */
|
||||
+typedef struct replica Replica;
|
||||
+
|
||||
+/* csn pending lists */
|
||||
+#define CSNPL_CTX_REPLCNT 4
|
||||
+typedef struct CSNPL_CTX
|
||||
+{
|
||||
+ CSN *prim_csn;
|
||||
+ size_t repl_alloc; /* max number of replicas */
|
||||
+ size_t repl_cnt; /* number of replicas affected by operation */
|
||||
+ Replica *prim_repl; /* pirmary replica */
|
||||
+ Replica **sec_repl; /* additional replicas affected */
|
||||
+} CSNPL_CTX;
|
||||
+
|
||||
/* In repl5_init.c */
|
||||
extern int repl5_is_betxn;
|
||||
char* get_thread_private_agmtname(void);
|
||||
void set_thread_private_agmtname (const char *agmtname);
|
||||
-void set_thread_primary_csn (const CSN *prim_csn);
|
||||
-CSN* get_thread_primary_csn(void);
|
||||
+void set_thread_primary_csn (const CSN *prim_csn, Replica *repl);
|
||||
+void add_replica_to_primcsn(CSNPL_CTX *prim_csn, Replica *repl);
|
||||
+CSNPL_CTX* get_thread_primary_csn(void);
|
||||
void* get_thread_private_cache(void);
|
||||
void set_thread_private_cache (void *buf);
|
||||
char* get_repl_session_id (Slapi_PBlock *pb, char *id, CSN **opcsn);
|
||||
@@ -302,7 +317,6 @@ typedef struct repl_bos Repl_Bos;
|
||||
|
||||
/* In repl5_agmt.c */
|
||||
typedef struct repl5agmt Repl_Agmt;
|
||||
-typedef struct replica Replica;
|
||||
|
||||
#define TRANSPORT_FLAG_SSL 1
|
||||
#define TRANSPORT_FLAG_TLS 2
|
||||
@@ -629,6 +643,8 @@ PRUint64 replica_get_precise_purging(Replica *r);
|
||||
void replica_set_precise_purging(Replica *r, PRUint64 on_off);
|
||||
PRBool ignore_error_and_keep_going(int error);
|
||||
void replica_check_release_timeout(Replica *r, Slapi_PBlock *pb);
|
||||
+void replica_lock_replica(Replica *r);
|
||||
+void replica_unlock_replica(Replica *r);
|
||||
|
||||
/* The functions below handles the state flag */
|
||||
/* Current internal state flags */
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
|
||||
index edffb84..b0bc515 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_init.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_init.c
|
||||
@@ -154,26 +154,62 @@ set_thread_private_agmtname(const char *agmtname)
|
||||
PR_SetThreadPrivate(thread_private_agmtname, (void *)agmtname);
|
||||
}
|
||||
|
||||
-CSN*
|
||||
+CSNPL_CTX*
|
||||
get_thread_primary_csn(void)
|
||||
{
|
||||
- CSN *prim_csn = NULL;
|
||||
+ CSNPL_CTX *prim_csn = NULL;
|
||||
if (thread_primary_csn)
|
||||
- prim_csn = (CSN *)PR_GetThreadPrivate(thread_primary_csn);
|
||||
+ prim_csn = (CSNPL_CTX *)PR_GetThreadPrivate(thread_primary_csn);
|
||||
+
|
||||
return prim_csn;
|
||||
}
|
||||
void
|
||||
-set_thread_primary_csn(const CSN *prim_csn)
|
||||
+set_thread_primary_csn (const CSN *prim_csn, Replica *repl)
|
||||
{
|
||||
if (thread_primary_csn) {
|
||||
if (prim_csn) {
|
||||
- PR_SetThreadPrivate(thread_primary_csn, (void *)csn_dup(prim_csn));
|
||||
+ CSNPL_CTX *csnpl_ctx = (CSNPL_CTX *)slapi_ch_calloc(1,sizeof(CSNPL_CTX));
|
||||
+ csnpl_ctx->prim_csn = csn_dup(prim_csn);
|
||||
+ /* repl_alloc, repl_cnt and sec_repl are 0 by calloc */
|
||||
+ csnpl_ctx->prim_repl = repl;
|
||||
+ PR_SetThreadPrivate(thread_primary_csn, (void *)csnpl_ctx);
|
||||
} else {
|
||||
PR_SetThreadPrivate(thread_primary_csn, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+add_replica_to_primcsn(CSNPL_CTX *csnpl_ctx, Replica *repl)
|
||||
+{
|
||||
+ size_t found = 0;
|
||||
+ size_t it = 0;
|
||||
+
|
||||
+ if (repl == csnpl_ctx->prim_repl) return;
|
||||
+
|
||||
+ while (it < csnpl_ctx->repl_cnt) {
|
||||
+ if (csnpl_ctx->sec_repl[it] == repl) {
|
||||
+ found = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ it++;
|
||||
+ }
|
||||
+ if (found) return;
|
||||
+
|
||||
+ if (csnpl_ctx->repl_cnt < csnpl_ctx->repl_alloc) {
|
||||
+ csnpl_ctx->sec_repl[csnpl_ctx->repl_cnt++] = repl;
|
||||
+ return;
|
||||
+ }
|
||||
+ csnpl_ctx->repl_alloc += CSNPL_CTX_REPLCNT;
|
||||
+ if (csnpl_ctx->repl_cnt == 0) {
|
||||
+ csnpl_ctx->sec_repl = (Replica **)slapi_ch_calloc(csnpl_ctx->repl_alloc, sizeof(Replica *));
|
||||
+ } else {
|
||||
+ csnpl_ctx->sec_repl = (Replica **)slapi_ch_realloc((char *)csnpl_ctx->sec_repl, csnpl_ctx->repl_alloc * sizeof(Replica *));
|
||||
+ }
|
||||
+ csnpl_ctx->sec_repl[csnpl_ctx->repl_cnt++] = repl;
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
void*
|
||||
get_thread_private_cache ()
|
||||
{
|
||||
@@ -740,7 +776,7 @@ multimaster_start( Slapi_PBlock *pb )
|
||||
/* Initialize thread private data for logging. Ignore if fails */
|
||||
PR_NewThreadPrivateIndex (&thread_private_agmtname, NULL);
|
||||
PR_NewThreadPrivateIndex (&thread_private_cache, NULL);
|
||||
- PR_NewThreadPrivateIndex (&thread_primary_csn, csnplFreeCSN);
|
||||
+ PR_NewThreadPrivateIndex (&thread_primary_csn, csnplFreeCSNPL_CTX);
|
||||
|
||||
/* Decode the command line args to see if we're dumping to LDIF */
|
||||
is_ldif_dump = check_for_ldif_dump(pb);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
index 9ef06af..c31d9d5 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "repl.h"
|
||||
#include "cl5_api.h"
|
||||
#include "urp.h"
|
||||
+#include "csnpl.h"
|
||||
|
||||
static char *local_purl = NULL;
|
||||
static char *purl_attrs[] = {"nsslapd-localhost", "nsslapd-port", "nsslapd-secureport", NULL};
|
||||
@@ -1034,7 +1035,7 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
|
||||
{
|
||||
Slapi_Operation *op = NULL;
|
||||
CSN *opcsn;
|
||||
- CSN *prim_csn;
|
||||
+ CSNPL_CTX *prim_csn;
|
||||
int rc;
|
||||
slapi_operation_parameters *op_params = NULL;
|
||||
Object *repl_obj = NULL;
|
||||
@@ -1070,14 +1071,15 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
|
||||
if (repl_obj == NULL)
|
||||
return return_value;
|
||||
|
||||
+ r = (Replica*)object_get_data (repl_obj);
|
||||
+ PR_ASSERT (r);
|
||||
+
|
||||
slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
|
||||
if (rc) { /* op failed - just return */
|
||||
cancel_opcsn(pb);
|
||||
goto common_return;
|
||||
}
|
||||
|
||||
- r = (Replica*)object_get_data (repl_obj);
|
||||
- PR_ASSERT (r);
|
||||
|
||||
replica_check_release_timeout(r, pb);
|
||||
|
||||
@@ -1223,12 +1225,12 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
|
||||
common_return:
|
||||
opcsn = operation_get_csn(op);
|
||||
prim_csn = get_thread_primary_csn();
|
||||
- if (csn_is_equal(opcsn, prim_csn)) {
|
||||
+ if (csn_primary(r, opcsn, prim_csn)) {
|
||||
if (return_value == 0) {
|
||||
/* the primary csn was succesfully committed
|
||||
* unset it in the thread local data
|
||||
*/
|
||||
- set_thread_primary_csn(NULL);
|
||||
+ set_thread_primary_csn(NULL, NULL);
|
||||
}
|
||||
}
|
||||
if (repl_obj) {
|
||||
@@ -1430,7 +1432,7 @@ cancel_opcsn (Slapi_PBlock *pb)
|
||||
|
||||
ruv_obj = replica_get_ruv (r);
|
||||
PR_ASSERT (ruv_obj);
|
||||
- ruv_cancel_csn_inprogress ((RUV*)object_get_data (ruv_obj), opcsn, replica_get_rid(r));
|
||||
+ ruv_cancel_csn_inprogress (r, (RUV*)object_get_data (ruv_obj), opcsn, replica_get_rid(r));
|
||||
object_release (ruv_obj);
|
||||
}
|
||||
|
||||
@@ -1491,7 +1493,7 @@ process_operation (Slapi_PBlock *pb, const CSN *csn)
|
||||
ruv = (RUV*)object_get_data (ruv_obj);
|
||||
PR_ASSERT (ruv);
|
||||
|
||||
- rc = ruv_add_csn_inprogress (ruv, csn);
|
||||
+ rc = ruv_add_csn_inprogress (r, ruv, csn);
|
||||
|
||||
object_release (ruv_obj);
|
||||
object_release (r_obj);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index 1bdc138..7927ac3 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -923,7 +923,7 @@ replica_update_ruv(Replica *r, const CSN *updated_csn, const char *replica_purl)
|
||||
}
|
||||
}
|
||||
/* Update max csn for local and remote replicas */
|
||||
- rc = ruv_update_ruv (ruv, updated_csn, replica_purl, r->repl_rid);
|
||||
+ rc = ruv_update_ruv (ruv, updated_csn, replica_purl, r, r->repl_rid);
|
||||
if (RUV_COVERS_CSN == rc)
|
||||
{
|
||||
slapi_log_err(SLAPI_LOG_REPL,
|
||||
@@ -3663,7 +3663,7 @@ assign_csn_callback(const CSN *csn, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
- ruv_add_csn_inprogress (ruv, csn);
|
||||
+ ruv_add_csn_inprogress (r, ruv, csn);
|
||||
|
||||
replica_unlock(r->repl_lock);
|
||||
|
||||
@@ -3692,13 +3692,13 @@ abort_csn_callback(const CSN *csn, void *data)
|
||||
{
|
||||
int rc = csnplRemove(r->min_csn_pl, csn);
|
||||
if (rc) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "abort_csn_callback - csnplRemove failed");
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "abort_csn_callback - csnplRemove failed\n");
|
||||
replica_unlock(r->repl_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- ruv_cancel_csn_inprogress (ruv, csn, replica_get_rid(r));
|
||||
+ ruv_cancel_csn_inprogress (r, ruv, csn, replica_get_rid(r));
|
||||
replica_unlock(r->repl_lock);
|
||||
|
||||
object_release (ruv_obj);
|
||||
@@ -4489,3 +4489,13 @@ replica_check_release_timeout(Replica *r, Slapi_PBlock *pb)
|
||||
}
|
||||
replica_unlock(r->repl_lock);
|
||||
}
|
||||
+void
|
||||
+replica_lock_replica(Replica *r)
|
||||
+{
|
||||
+ replica_lock(r->repl_lock);
|
||||
+}
|
||||
+void
|
||||
+replica_unlock_replica(Replica *r)
|
||||
+{
|
||||
+ replica_unlock(r->repl_lock);
|
||||
+}
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
index d59e6d2..39449b6 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
@@ -77,7 +77,7 @@ static char *get_replgen_from_berval(const struct berval *bval);
|
||||
static const char * const prefix_replicageneration = "{replicageneration}";
|
||||
static const char * const prefix_ruvcsn = "{replica "; /* intentionally missing '}' */
|
||||
|
||||
-static int ruv_update_ruv_element (RUV *ruv, RUVElement *replica, const CSN *csn, const char *replica_purl, PRBool isLocal);
|
||||
+static int ruv_update_ruv_element (RUV *ruv, RUVElement *replica, const CSNPL_CTX *prim_csn, const char *replica_purl, PRBool isLocal);
|
||||
|
||||
/* API implementation */
|
||||
|
||||
@@ -1599,13 +1599,13 @@ ruv_dump(const RUV *ruv, char *ruv_name, PRFileDesc *prFile)
|
||||
|
||||
/* this function notifies the ruv that there are operations in progress so that
|
||||
they can be added to the pending list for the appropriate client. */
|
||||
-int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
|
||||
+int ruv_add_csn_inprogress (void *repl, RUV *ruv, const CSN *csn)
|
||||
{
|
||||
RUVElement* replica;
|
||||
char csn_str[CSN_STRSIZE];
|
||||
int rc = RUV_SUCCESS;
|
||||
int rid = csn_get_replicaid (csn);
|
||||
- CSN *prim_csn;
|
||||
+ CSNPL_CTX *prim_csn;
|
||||
|
||||
PR_ASSERT (ruv && csn);
|
||||
|
||||
@@ -1645,8 +1645,13 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
|
||||
}
|
||||
prim_csn = get_thread_primary_csn();
|
||||
if (prim_csn == NULL) {
|
||||
- set_thread_primary_csn(csn);
|
||||
+ set_thread_primary_csn(csn, (Replica *)repl);
|
||||
prim_csn = get_thread_primary_csn();
|
||||
+ } else {
|
||||
+ /* the prim csn data already exist, need to check if
|
||||
+ * current replica is already present
|
||||
+ */
|
||||
+ add_replica_to_primcsn(prim_csn, (Replica *)repl);
|
||||
}
|
||||
rc = csnplInsert (replica->csnpl, csn, prim_csn);
|
||||
if (rc == 1) /* we already seen this csn */
|
||||
@@ -1656,7 +1661,7 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
|
||||
"The csn %s has already be seen - ignoring\n",
|
||||
csn_as_string (csn, PR_FALSE, csn_str));
|
||||
}
|
||||
- set_thread_primary_csn(NULL);
|
||||
+ set_thread_primary_csn(NULL, NULL);
|
||||
rc = RUV_COVERS_CSN;
|
||||
}
|
||||
else if(rc != 0)
|
||||
@@ -1681,11 +1686,13 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn, ReplicaId local_rid)
|
||||
+int ruv_cancel_csn_inprogress (void *repl, RUV *ruv, const CSN *csn, ReplicaId local_rid)
|
||||
{
|
||||
- RUVElement* replica;
|
||||
+ RUVElement* repl_ruv;
|
||||
int rc = RUV_SUCCESS;
|
||||
- CSN *prim_csn = NULL;
|
||||
+ CSNPL_CTX *prim_csn = NULL;
|
||||
+ Replica *repl_it;
|
||||
+ size_t it;
|
||||
|
||||
|
||||
PR_ASSERT (ruv && csn);
|
||||
@@ -1693,29 +1700,53 @@ int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn, ReplicaId local_rid)
|
||||
prim_csn = get_thread_primary_csn();
|
||||
/* locate ruvElement */
|
||||
slapi_rwlock_wrlock (ruv->lock);
|
||||
- replica = ruvGetReplica (ruv, csn_get_replicaid (csn));
|
||||
- if (replica == NULL) {
|
||||
+ repl_ruv = ruvGetReplica (ruv, csn_get_replicaid (csn));
|
||||
+ if (repl_ruv == NULL) {
|
||||
/* ONREPL - log error */
|
||||
rc = RUV_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
- if (csn_is_equal(csn, prim_csn)) {
|
||||
- /* the prim csn is cancelled, lets remove all dependent csns */
|
||||
- ReplicaId prim_rid = csn_get_replicaid (csn);
|
||||
- replica = ruvGetReplica (ruv, prim_rid);
|
||||
- rc = csnplRemoveAll (replica->csnpl, prim_csn);
|
||||
- if (prim_rid != local_rid) {
|
||||
- if( local_rid != READ_ONLY_REPLICA_ID) {
|
||||
- replica = ruvGetReplica (ruv, local_rid);
|
||||
- if (replica) {
|
||||
- rc = csnplRemoveAll (replica->csnpl, prim_csn);
|
||||
- } else {
|
||||
- rc = RUV_NOTFOUND;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ if (csn_primary(repl, csn, prim_csn)) {
|
||||
+ /* the prim csn is cancelled, lets remove all dependent csns */
|
||||
+ /* for the primary replica we can have modifications for two RIDS:
|
||||
+ * - the local RID for direct or internal operations
|
||||
+ * - a remote RID if the primary csn is for a replciated op.
|
||||
+ */
|
||||
+ ReplicaId prim_rid = csn_get_replicaid(csn);
|
||||
+ repl_ruv = ruvGetReplica(ruv, prim_rid);
|
||||
+ if (!repl_ruv) {
|
||||
+ rc = RUV_NOTFOUND;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ rc = csnplRemoveAll(repl_ruv->csnpl, prim_csn);
|
||||
+
|
||||
+ if (prim_rid != local_rid && local_rid != READ_ONLY_REPLICA_ID) {
|
||||
+ repl_ruv = ruvGetReplica(ruv, local_rid);
|
||||
+ if (!repl_ruv) {
|
||||
+ rc = RUV_NOTFOUND;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ rc = csnplRemoveAll(repl_ruv->csnpl, prim_csn);
|
||||
+ }
|
||||
+
|
||||
+ for (it = 0; it < prim_csn->repl_cnt; it++) {
|
||||
+ repl_it = prim_csn->sec_repl[it];
|
||||
+ replica_lock_replica(repl_it);
|
||||
+ local_rid = replica_get_rid(repl_it);
|
||||
+ if (local_rid != READ_ONLY_REPLICA_ID) {
|
||||
+ Object *ruv_obj = replica_get_ruv(repl_it);
|
||||
+ RUV *ruv_it = object_get_data(ruv_obj);
|
||||
+ repl_ruv = ruvGetReplica(ruv_it, local_rid);
|
||||
+ if (repl_ruv) {
|
||||
+ rc = csnplRemoveAll(repl_ruv->csnpl, prim_csn);
|
||||
+ } else {
|
||||
+ rc = RUV_NOTFOUND;
|
||||
+ }
|
||||
+ }
|
||||
+ replica_unlock_replica(repl_it);
|
||||
+ }
|
||||
} else {
|
||||
- rc = csnplRemove (replica->csnpl, csn);
|
||||
+ rc = csnplRemove (repl_ruv->csnpl, csn);
|
||||
}
|
||||
if (rc != 0)
|
||||
rc = RUV_NOTFOUND;
|
||||
@@ -1727,86 +1758,100 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, ReplicaId local_rid)
|
||||
+int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, void *replica, ReplicaId local_rid)
|
||||
{
|
||||
int rc=RUV_SUCCESS;
|
||||
- RUVElement *replica;
|
||||
+ RUVElement *repl_ruv;
|
||||
ReplicaId prim_rid;
|
||||
+ Replica *repl_it = NULL;
|
||||
+ size_t it = 0;
|
||||
|
||||
- CSN *prim_csn = get_thread_primary_csn();
|
||||
+ CSNPL_CTX *prim_csn = get_thread_primary_csn();
|
||||
|
||||
- if (! csn_is_equal(csn, prim_csn)) {
|
||||
+ if (! csn_primary(replica, csn, prim_csn)) {
|
||||
/* not a primary csn, nothing to do */
|
||||
return rc;
|
||||
}
|
||||
- slapi_rwlock_wrlock (ruv->lock);
|
||||
+
|
||||
+ /* first handle primary replica
|
||||
+ * there can be two ruv elements affected
|
||||
+ */
|
||||
prim_rid = csn_get_replicaid (csn);
|
||||
- replica = ruvGetReplica (ruv, local_rid);
|
||||
- rc = ruv_update_ruv_element(ruv, replica, csn, replica_purl, PR_TRUE);
|
||||
- if ( rc || local_rid == prim_rid) goto done;
|
||||
- replica = ruvGetReplica (ruv, prim_rid);
|
||||
- rc = ruv_update_ruv_element(ruv, replica, csn, replica_purl, PR_FALSE);
|
||||
-done:
|
||||
+ slapi_rwlock_wrlock (ruv->lock);
|
||||
+ if ( local_rid != prim_rid) {
|
||||
+ repl_ruv = ruvGetReplica (ruv, prim_rid);
|
||||
+ rc = ruv_update_ruv_element(ruv, repl_ruv, prim_csn, replica_purl, PR_FALSE);
|
||||
+ }
|
||||
+ repl_ruv = ruvGetReplica (ruv, local_rid);
|
||||
+ rc = ruv_update_ruv_element(ruv, repl_ruv, prim_csn, replica_purl, PR_TRUE);
|
||||
slapi_rwlock_unlock (ruv->lock);
|
||||
+ if (rc) return rc;
|
||||
+
|
||||
+ /* now handle secondary replicas */
|
||||
+ for (it=0; it<prim_csn->repl_cnt; it++) {
|
||||
+ repl_it = prim_csn->sec_repl[it];
|
||||
+ replica_lock_replica(repl_it);
|
||||
+ Object *ruv_obj = replica_get_ruv (repl_it);
|
||||
+ RUV *ruv_it = object_get_data (ruv_obj);
|
||||
+ slapi_rwlock_wrlock (ruv_it->lock);
|
||||
+ repl_ruv = ruvGetReplica (ruv_it, replica_get_rid(repl_it));
|
||||
+ rc = ruv_update_ruv_element(ruv_it, repl_ruv, prim_csn, replica_purl, PR_TRUE);
|
||||
+ slapi_rwlock_unlock (ruv_it->lock);
|
||||
+ replica_unlock_replica(repl_it);
|
||||
+ if (rc) break;
|
||||
+ }
|
||||
return rc;
|
||||
}
|
||||
+
|
||||
static int
|
||||
-ruv_update_ruv_element (RUV *ruv, RUVElement *replica, const CSN *csn, const char *replica_purl, PRBool isLocal)
|
||||
+ruv_update_ruv_element (RUV *ruv, RUVElement *replica, const CSNPL_CTX *prim_csn, const char *replica_purl, PRBool isLocal)
|
||||
{
|
||||
int rc=RUV_SUCCESS;
|
||||
char csn_str[CSN_STRSIZE];
|
||||
CSN *max_csn;
|
||||
CSN *first_csn = NULL;
|
||||
|
||||
- if (replica == NULL)
|
||||
- {
|
||||
+ if (replica == NULL) {
|
||||
/* we should have a ruv element at this point because it would have
|
||||
been added by ruv_add_inprogress function */
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "ruv_update_ruv - "
|
||||
- "Can't locate RUV element for replica %d\n", csn_get_replicaid (csn));
|
||||
+ "Can't locate RUV element for replica %d\n", csn_get_replicaid (prim_csn->prim_csn));
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (csnplCommitAll(replica->csnpl, csn) != 0)
|
||||
- {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "ruv_update_ruv - Cannot commit csn %s\n",
|
||||
- csn_as_string(csn, PR_FALSE, csn_str));
|
||||
+ if (csnplCommitAll(replica->csnpl, prim_csn) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "ruv_update_ruv - Cannot commit csn %s\n",
|
||||
+ csn_as_string(prim_csn->prim_csn, PR_FALSE, csn_str));
|
||||
rc = RUV_CSNPL_ERROR;
|
||||
goto done;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
+ } else {
|
||||
if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "ruv_update_ruv - "
|
||||
- "Successfully committed csn %s\n", csn_as_string(csn, PR_FALSE, csn_str));
|
||||
+ "Successfully committed csn %s\n", csn_as_string(prim_csn->prim_csn, PR_FALSE, csn_str));
|
||||
}
|
||||
}
|
||||
|
||||
- if ((max_csn = csnplRollUp(replica->csnpl, &first_csn)) != NULL)
|
||||
- {
|
||||
-#ifdef DEBUG
|
||||
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "ruv_update_ruv - Rolled up to csn %s\n",
|
||||
- csn_as_string(max_csn, PR_FALSE, csn_str)); /* XXXggood remove debugging */
|
||||
-#endif
|
||||
+ if ((max_csn = csnplRollUp(replica->csnpl, &first_csn)) != NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "ruv_update_ruv - Rolled up to csn %s\n",
|
||||
+ csn_as_string(max_csn, PR_FALSE, csn_str)); /* XXXggood remove debugging */
|
||||
/* replica object sets min csn for local replica */
|
||||
- if (!isLocal && replica->min_csn == NULL) {
|
||||
- /* bug 559223 - it seems that, under huge stress, a server might pass
|
||||
- * through this code when more than 1 change has already been sent and commited into
|
||||
- * the pending lists... Therefore, as we are trying to set the min_csn ever
|
||||
- * generated by this replica, we need to set the first_csn as the min csn in the
|
||||
- * ruv */
|
||||
- set_min_csn_nolock(ruv, first_csn, replica_purl);
|
||||
- }
|
||||
- /* only update the max_csn in the RUV if it is greater than the existing one */
|
||||
- rc = set_max_csn_nolock_ext(ruv, max_csn, replica_purl, PR_TRUE /* must be greater */);
|
||||
- /* It is possible that first_csn points to max_csn.
|
||||
- We need to free it once */
|
||||
- if (max_csn != first_csn) {
|
||||
- csn_free(&first_csn);
|
||||
- }
|
||||
- csn_free(&max_csn);
|
||||
- }
|
||||
-
|
||||
+ if (!isLocal && replica->min_csn == NULL) {
|
||||
+ /* bug 559223 - it seems that, under huge stress, a server might pass
|
||||
+ * through this code when more than 1 change has already been sent and commited into
|
||||
+ * the pending lists... Therefore, as we are trying to set the min_csn ever
|
||||
+ * generated by this replica, we need to set the first_csn as the min csn in the
|
||||
+ * ruv */
|
||||
+ set_min_csn_nolock(ruv, first_csn, replica_purl);
|
||||
+ }
|
||||
+ /* only update the max_csn in the RUV if it is greater than the existing one */
|
||||
+ rc = set_max_csn_nolock_ext(ruv, max_csn, replica_purl, PR_TRUE /* must be greater */);
|
||||
+ /* It is possible that first_csn points to max_csn.
|
||||
+ We need to free it once */
|
||||
+ if (max_csn != first_csn) {
|
||||
+ csn_free(&first_csn);
|
||||
+ }
|
||||
+ csn_free(&max_csn);
|
||||
+ }
|
||||
done:
|
||||
|
||||
return rc;
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_ruv.h b/ldap/servers/plugins/replication/repl5_ruv.h
|
||||
index c8960fd..f3cd38b 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_ruv.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5_ruv.h
|
||||
@@ -108,9 +108,9 @@ int ruv_to_bervals(const RUV *ruv, struct berval ***bvals);
|
||||
PRInt32 ruv_replica_count (const RUV *ruv);
|
||||
char **ruv_get_referrals(const RUV *ruv);
|
||||
void ruv_dump(const RUV *ruv, char *ruv_name, PRFileDesc *prFile);
|
||||
-int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn);
|
||||
-int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn, ReplicaId rid);
|
||||
-int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, ReplicaId local_rid);
|
||||
+int ruv_add_csn_inprogress (void *repl, RUV *ruv, const CSN *csn);
|
||||
+int ruv_cancel_csn_inprogress (void *repl, RUV *ruv, const CSN *csn, ReplicaId rid);
|
||||
+int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, void *replica, ReplicaId local_rid);
|
||||
int ruv_move_local_supplier_to_first(RUV *ruv, ReplicaId rid);
|
||||
int ruv_get_first_id_and_purl(RUV *ruv, ReplicaId *rid, char **replica_purl );
|
||||
int ruv_local_contains_supplier(RUV *ruv, ReplicaId rid);
|
||||
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
||||
index 0836d66..3910dbe 100644
|
||||
--- a/ldap/servers/slapd/slapi-private.h
|
||||
+++ b/ldap/servers/slapd/slapi-private.h
|
||||
@@ -193,7 +193,7 @@ const CSN *csn_max(const CSN *csn1,const CSN *csn2);
|
||||
a csn from the set.*/
|
||||
int csn_increment_subsequence (CSN *csn);
|
||||
|
||||
-void csnplFreeCSN (void *arg);
|
||||
+void csnplFreeCSNPL_CTX (void *arg);
|
||||
/*
|
||||
* csnset.c
|
||||
*/
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
From 95b39e29361812a62f2e038c89a88d717c82794e Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 31 Jul 2017 14:13:49 +1000
|
||||
Subject: [PATCH] Ticket 49336 - SECURITY: Locked account provides different
|
||||
return code
|
||||
|
||||
Bug Description: The directory server password lockout policy prevents binds
|
||||
from operating once a threshold of failed passwords has been met. During
|
||||
this lockout, if you bind with a successful password, a different error code
|
||||
is returned. This means that an attacker has no ratelimit or penalty during
|
||||
an account lock, and can continue to attempt passwords via bruteforce, using
|
||||
the change in return code to ascertain a sucessful password auth.
|
||||
|
||||
Fix Description: Move the account lock check *before* the password bind
|
||||
check. If the account is locked, we do not mind disclosing this as the
|
||||
attacker will either ignore it (and will not bind anyway), or they will
|
||||
be forced to back off as the attack is not working preventing the
|
||||
bruteforce.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49336
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: tbordaz (Thanks!)
|
||||
|
||||
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
|
||||
---
|
||||
.../suites/password/pwd_lockout_bypass_test.py | 55 ++++++++++++++++++++++
|
||||
ldap/servers/slapd/bind.c | 29 ++++++++----
|
||||
ldap/servers/slapd/pw_verify.c | 15 +++---
|
||||
3 files changed, 84 insertions(+), 15 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py b/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
|
||||
new file mode 100644
|
||||
index 0000000..e4add72
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/password/pwd_lockout_bypass_test.py
|
||||
@@ -0,0 +1,55 @@
|
||||
+# --- 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
|
||||
+from lib389.tasks import *
|
||||
+from lib389.utils import *
|
||||
+from lib389.topologies import topology_st
|
||||
+from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
|
||||
+import ldap
|
||||
+
|
||||
+# The irony of these names is not lost on me.
|
||||
+GOOD_PASSWORD = 'password'
|
||||
+BAD_PASSWORD = 'aontseunao'
|
||||
+
|
||||
+logging.getLogger(__name__).setLevel(logging.INFO)
|
||||
+log = logging.getLogger(__name__)
|
||||
+
|
||||
+def test_lockout_bypass(topology_st):
|
||||
+ inst = topology_st.standalone
|
||||
+
|
||||
+ # Configure the lock policy
|
||||
+ inst.config.set('passwordMaxFailure', '1')
|
||||
+ inst.config.set('passwordLockoutDuration', '99999')
|
||||
+ inst.config.set('passwordLockout', 'on')
|
||||
+
|
||||
+ # Create the account
|
||||
+ users = UserAccounts(inst, DEFAULT_SUFFIX)
|
||||
+ testuser = users.create(properties=TEST_USER_PROPERTIES)
|
||||
+ testuser.set('userPassword', GOOD_PASSWORD)
|
||||
+
|
||||
+ conn = testuser.bind(GOOD_PASSWORD)
|
||||
+ assert conn != None
|
||||
+ conn.unbind_s()
|
||||
+
|
||||
+ # Bind with bad creds twice
|
||||
+ # This is the failure.
|
||||
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
+ conn = testuser.bind(BAD_PASSWORD)
|
||||
+ # Now we should not be able to ATTEMPT the bind. It doesn't matter that
|
||||
+ # we disclose that we have hit the rate limit here, what matters is that
|
||||
+ # it exists.
|
||||
+ with pytest.raises(ldap.CONSTRAINT_VIOLATION):
|
||||
+ conn = testuser.bind(BAD_PASSWORD)
|
||||
+
|
||||
+ # now bind with good creds
|
||||
+ # Should be error 19 still.
|
||||
+ with pytest.raises(ldap.CONSTRAINT_VIOLATION):
|
||||
+ conn = testuser.bind(GOOD_PASSWORD)
|
||||
+
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
||||
index 7f4414f..064ace1 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -662,12 +662,14 @@ do_bind( Slapi_PBlock *pb )
|
||||
/* We could be serving multiple database backends. Select the appropriate one */
|
||||
/* pw_verify_be_dn will select the backend we need for us. */
|
||||
|
||||
- if (auto_bind) {
|
||||
- /* We have no password material. We should just check who we are binding as. */
|
||||
- rc = pw_validate_be_dn(pb, &referral);
|
||||
- } else {
|
||||
- rc = pw_verify_be_dn(pb, &referral);
|
||||
- }
|
||||
+ /*
|
||||
+ * WARNING: We have to validate *all* other conditions *first* before
|
||||
+ * we attempt the bind!
|
||||
+ *
|
||||
+ * this is because ldbm_bind.c will SEND THE FAILURE.
|
||||
+ */
|
||||
+
|
||||
+ rc = pw_validate_be_dn(pb, &referral);
|
||||
|
||||
if (rc == SLAPI_BIND_NO_BACKEND) {
|
||||
send_nobackend_ldap_result( pb );
|
||||
@@ -736,8 +738,18 @@ do_bind( Slapi_PBlock *pb )
|
||||
myrc = 0;
|
||||
}
|
||||
if (!auto_bind) {
|
||||
- /*
|
||||
- * There could be a race that bind_target_entry was not added
|
||||
+ /*
|
||||
+ * Okay, we've made it here. FINALLY check if the entry really
|
||||
+ * can bind or not. THIS IS THE PASSWORD CHECK.
|
||||
+ */
|
||||
+ rc = pw_verify_be_dn(pb, &referral);
|
||||
+ if (rc != SLAPI_BIND_SUCCESS) {
|
||||
+ /* Invalid pass - lets bail ... */
|
||||
+ goto bind_failed;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * There could be a race that bind_target_entry was not added
|
||||
* when bind_target_entry was retrieved before be_bind, but it
|
||||
* was in be_bind. Since be_bind returned SLAPI_BIND_SUCCESS,
|
||||
* the entry is in the DS. So, we need to retrieve it once more.
|
||||
@@ -786,6 +798,7 @@ do_bind( Slapi_PBlock *pb )
|
||||
}
|
||||
}
|
||||
} else { /* if auto_bind || rc == slapi_bind_success | slapi_bind_anonymous */
|
||||
+ bind_failed:
|
||||
if (rc == LDAP_OPERATIONS_ERROR) {
|
||||
send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL );
|
||||
goto free_and_return;
|
||||
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
||||
index 852b027..cb182ed 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.c
|
||||
+++ b/ldap/servers/slapd/pw_verify.c
|
||||
@@ -55,7 +55,7 @@ pw_verify_root_dn(const char *dn, const Slapi_Value *cred)
|
||||
int
|
||||
pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
{
|
||||
- int rc = 0;
|
||||
+ int rc = SLAPI_BIND_SUCCESS;
|
||||
Slapi_Backend *be = NULL;
|
||||
|
||||
if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
||||
@@ -109,14 +109,10 @@ pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &cred);
|
||||
slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method);
|
||||
|
||||
- if (pb_sdn != NULL || cred != NULL) {
|
||||
+ if (pb_sdn == NULL) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
- if (*referral) {
|
||||
- return SLAPI_BIND_REFERRAL;
|
||||
- }
|
||||
-
|
||||
/* We need a slapi_sdn_isanon? */
|
||||
if (method == LDAP_AUTH_SIMPLE && cred->bv_len == 0) {
|
||||
return SLAPI_BIND_ANONYMOUS;
|
||||
@@ -130,7 +126,11 @@ pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
||||
return SLAPI_BIND_NO_BACKEND;
|
||||
}
|
||||
- slapi_be_Unlock(be);
|
||||
+
|
||||
+ if (*referral) {
|
||||
+ slapi_be_Unlock(be);
|
||||
+ return SLAPI_BIND_REFERRAL;
|
||||
+ }
|
||||
|
||||
slapi_pblock_set(pb, SLAPI_BACKEND, be);
|
||||
slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
|
||||
@@ -138,6 +138,7 @@ pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
set_db_default_result_handlers(pb);
|
||||
|
||||
/* The backend associated with this identity is real. */
|
||||
+ slapi_be_Unlock(be);
|
||||
|
||||
return SLAPI_BIND_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.9.4
|
||||
|
177
SOURCES/0059-Ticket-49298-force-sync-on-shutdown.patch
Normal file
177
SOURCES/0059-Ticket-49298-force-sync-on-shutdown.patch
Normal file
|
@ -0,0 +1,177 @@
|
|||
From ba30cc562f5ebd58955502a19edbf9720a45b655 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 8 Aug 2017 13:02:53 -0400
|
||||
Subject: [PATCH] Ticket 49298 - force sync() on shutdown
|
||||
|
||||
Bug Description: During shutdown on xfs we would occasionally
|
||||
see a broke dse.ldif (specifically, empty). This happens due to
|
||||
a bug in xfs where the directory isn't synced on rename().
|
||||
|
||||
Fix Description: As we shutdown call sync() to force all our
|
||||
writes to disk - dse.ldif, logs, db, all of it.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49298
|
||||
---
|
||||
ldap/servers/slapd/dse.c | 59 +++++++++++++++++++++++++++++------------------
|
||||
ldap/servers/slapd/main.c | 9 ++++----
|
||||
2 files changed, 42 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
||||
index 5715c83..fa1aacc 100644
|
||||
--- a/ldap/servers/slapd/dse.c
|
||||
+++ b/ldap/servers/slapd/dse.c
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "slap.h"
|
||||
#include <pwd.h>
|
||||
|
||||
+#include <unistd.h> /* provides fsync/close */
|
||||
+
|
||||
/* #define SLAPI_DSE_DEBUG */ /* define this to force trace log */
|
||||
/* messages to always be logged */
|
||||
|
||||
@@ -72,11 +74,11 @@
|
||||
struct dse_callback
|
||||
{
|
||||
int operation;
|
||||
- int flags;
|
||||
- Slapi_DN *base;
|
||||
- int scope;
|
||||
- char *filter; /* NULL means match all entries */
|
||||
- Slapi_Filter *slapifilter; /* NULL means match all entries */
|
||||
+ int flags;
|
||||
+ Slapi_DN *base;
|
||||
+ int scope;
|
||||
+ char *filter; /* NULL means match all entries */
|
||||
+ Slapi_Filter *slapifilter; /* NULL means match all entries */
|
||||
int (*fn)(Slapi_PBlock *,Slapi_Entry *,Slapi_Entry *,int*,char*,void *);
|
||||
void *fn_arg;
|
||||
struct slapdplugin *plugin;
|
||||
@@ -89,13 +91,14 @@ struct dse
|
||||
char *dse_tmpfile; /* and written to when changes are made via LDAP */
|
||||
char *dse_fileback; /* contain the latest info, just before a new change */
|
||||
char *dse_filestartOK; /* contain the latest info with which the server has successfully started */
|
||||
+ char *dse_configdir; /* The location of config files - allows us to fsync the dir post rename */
|
||||
Avlnode *dse_tree;
|
||||
struct dse_callback *dse_callback;
|
||||
Slapi_RWLock *dse_rwlock; /* a read-write lock to protect the whole dse backend */
|
||||
- char **dse_filelist; /* these are additional read only files used to */
|
||||
- /* initialize the dse */
|
||||
- int dse_is_updateable; /* if non-zero, this DSE can be written to */
|
||||
- int dse_readonly_error_reported; /* used to ensure that read-only errors are logged only once */
|
||||
+ char **dse_filelist; /* these are additional read only files used to */
|
||||
+ /* initialize the dse */
|
||||
+ int dse_is_updateable; /* if non-zero, this DSE can be written to */
|
||||
+ int dse_readonly_error_reported; /* used to ensure that read-only errors are logged only once */
|
||||
};
|
||||
|
||||
struct dse_node
|
||||
@@ -361,37 +364,39 @@ dse_new( char *filename, char *tmpfilename, char *backfilename, char *startokfil
|
||||
if (!strstr(filename, realconfigdir))
|
||||
{
|
||||
pdse->dse_filename = slapi_ch_smprintf("%s/%s", realconfigdir, filename );
|
||||
- }
|
||||
- else
|
||||
+ } else {
|
||||
pdse->dse_filename = slapi_ch_strdup(filename);
|
||||
+ }
|
||||
|
||||
if (!strstr(tmpfilename, realconfigdir)) {
|
||||
pdse->dse_tmpfile = slapi_ch_smprintf("%s/%s", realconfigdir, tmpfilename );
|
||||
- }
|
||||
- else
|
||||
+ } else {
|
||||
pdse->dse_tmpfile = slapi_ch_strdup(tmpfilename);
|
||||
+ }
|
||||
+
|
||||
+ pdse->dse_configdir = slapi_ch_strdup(realconfigdir);
|
||||
|
||||
if ( backfilename != NULL )
|
||||
{
|
||||
if (!strstr(backfilename, realconfigdir)) {
|
||||
pdse->dse_fileback = slapi_ch_smprintf("%s/%s", realconfigdir, backfilename );
|
||||
- }
|
||||
- else
|
||||
+ } else {
|
||||
pdse->dse_fileback = slapi_ch_strdup(backfilename);
|
||||
- }
|
||||
- else
|
||||
+ }
|
||||
+ } else {
|
||||
pdse->dse_fileback = NULL;
|
||||
+ }
|
||||
|
||||
if ( startokfilename != NULL )
|
||||
{
|
||||
if (!strstr(startokfilename, realconfigdir)) {
|
||||
pdse->dse_filestartOK = slapi_ch_smprintf("%s/%s", realconfigdir, startokfilename );
|
||||
- }
|
||||
- else
|
||||
+ } else {
|
||||
pdse->dse_filestartOK = slapi_ch_strdup(startokfilename);
|
||||
- }
|
||||
- else
|
||||
+ }
|
||||
+ } else {
|
||||
pdse->dse_filestartOK = NULL;
|
||||
+ }
|
||||
|
||||
pdse->dse_tree= NULL;
|
||||
pdse->dse_callback= NULL;
|
||||
@@ -440,6 +445,7 @@ dse_destroy(struct dse *pdse)
|
||||
slapi_ch_free((void **)&(pdse->dse_tmpfile));
|
||||
slapi_ch_free((void **)&(pdse->dse_fileback));
|
||||
slapi_ch_free((void **)&(pdse->dse_filestartOK));
|
||||
+ slapi_ch_free((void **)&(pdse->dse_configdir));
|
||||
dse_callback_deletelist(&pdse->dse_callback);
|
||||
charray_free(pdse->dse_filelist);
|
||||
nentries = avl_free(pdse->dse_tree, dse_internal_delete_entry);
|
||||
@@ -991,8 +997,9 @@ dse_write_file_nolock(struct dse* pdse)
|
||||
FPWrapper fpw;
|
||||
int rc = 0;
|
||||
|
||||
- if (dont_ever_write_dse_files)
|
||||
+ if (dont_ever_write_dse_files) {
|
||||
return rc;
|
||||
+ }
|
||||
|
||||
fpw.fpw_rc = 0;
|
||||
fpw.fpw_prfd = NULL;
|
||||
@@ -1042,6 +1049,14 @@ dse_write_file_nolock(struct dse* pdse)
|
||||
pdse->dse_tmpfile, pdse->dse_filename,
|
||||
rc, slapd_system_strerror( rc ));
|
||||
}
|
||||
+ /*
|
||||
+ * We have now written to the tmp location, and renamed it
|
||||
+ * we need to open and fsync the dir to make the rename stick.
|
||||
+ */
|
||||
+ int fp_configdir = open(pdse->dse_configdir, O_PATH | O_DIRECTORY);
|
||||
+ fsync(fp_configdir);
|
||||
+ close(fp_configdir);
|
||||
+
|
||||
}
|
||||
}
|
||||
if (fpw.fpw_prfd)
|
||||
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
||||
index ba1f5e8..3351464 100644
|
||||
--- a/ldap/servers/slapd/main.c
|
||||
+++ b/ldap/servers/slapd/main.c
|
||||
@@ -1154,11 +1154,12 @@ cleanup:
|
||||
ndn_cache_destroy();
|
||||
NSS_Shutdown();
|
||||
PR_Cleanup();
|
||||
-#if defined( hpux )
|
||||
- exit( return_value );
|
||||
-#else
|
||||
+ /*
|
||||
+ * Server has stopped, lets force everything to disk: logs
|
||||
+ * db, dse.ldif, all of it.
|
||||
+ */
|
||||
+ sync();
|
||||
return return_value;
|
||||
-#endif
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
From c903f66194f04e97fc684f5a9654cedb27530931 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Mon, 31 Jul 2017 10:51:08 +0200
|
||||
Subject: [PATCH 1/3] Ticket 49334 - fix backup restore if changelog exists
|
||||
|
||||
The corrcect flag to copy a directory in backup/restore must be passed for the changelog directory
|
||||
|
||||
Reviewed by: William, thanks
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/dblayer.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
index ff97aa4..3a97f2f 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
|
||||
@@ -6143,7 +6143,7 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
|
||||
return_value = dblayer_copy_directory(li, task, changelogdir,
|
||||
changelog_destdir,
|
||||
0 /* backup */,
|
||||
- &cnt, 1, 0, 0);
|
||||
+ &cnt, 0, 0, 1);
|
||||
if (return_value) {
|
||||
slapi_log_err(SLAPI_LOG_ERR,
|
||||
"dblayer_backup", "Error in copying directory "
|
||||
@@ -6823,7 +6823,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
|
||||
*cldirname = '\0';
|
||||
return_value = dblayer_copy_directory(li, task, filename1,
|
||||
changelogdir, 1 /* restore */,
|
||||
- &cnt, 1, 0 ,0);
|
||||
+ &cnt, 0, 0 ,1);
|
||||
*cldirname = '/';
|
||||
if (return_value) {
|
||||
slapi_log_err(SLAPI_LOG_ERR,
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
From b0954a5df7841330732a5ab532c528a68cf380cf Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Fri, 18 Aug 2017 13:00:46 +1000
|
||||
Subject: [PATCH] Ticket 49356 - mapping tree crash can occur during tot init
|
||||
|
||||
Bug Description: Two faults were found in the handling of the mapping
|
||||
tree of 389 directory server. The first fault was that the tree-free
|
||||
check was not performed atomically and may cause an incorrect operations
|
||||
error to be returned. The second was that during a total init the referral
|
||||
would not lock the be, but the pw_verify code assumed a be was locked.
|
||||
This caused a segfault.
|
||||
|
||||
Fix Description: Fix the freed check to use atomics. Fix the pw_verify
|
||||
to assert be is NULL (which is correct, there is no backend).
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49356
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: mreynolds (THanks!)
|
||||
---
|
||||
.../mapping_tree/referral_during_tot_init.py | 57 ++++++++
|
||||
ldap/servers/slapd/fedse.c | 10 ++
|
||||
ldap/servers/slapd/main.c | 10 --
|
||||
ldap/servers/slapd/mapping_tree.c | 150 +++++++++++----------
|
||||
ldap/servers/slapd/pw_verify.c | 8 +-
|
||||
5 files changed, 150 insertions(+), 85 deletions(-)
|
||||
create mode 100644 dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
||||
new file mode 100644
|
||||
index 0000000..e5aee7d
|
||||
--- /dev/null
|
||||
+++ b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py
|
||||
@@ -0,0 +1,57 @@
|
||||
+# --- 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 ldap
|
||||
+import pytest
|
||||
+from lib389.topologies import topology_m2
|
||||
+from lib389._constants import (DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2, TASK_WAIT)
|
||||
+
|
||||
+from lib389.idm.user import (TEST_USER_PROPERTIES, UserAccounts)
|
||||
+
|
||||
+def test_referral_during_tot(topology_m2):
|
||||
+
|
||||
+ master1 = topology_m2.ms["master1"]
|
||||
+ master2 = topology_m2.ms["master2"]
|
||||
+
|
||||
+ # Create a bunch of entries on master1
|
||||
+ ldif_dir = master1.get_ldif_dir()
|
||||
+ import_ldif = ldif_dir + '/ref_during_tot_import.ldif'
|
||||
+ master1.buildLDIF(10000, import_ldif)
|
||||
+
|
||||
+ master1.stop()
|
||||
+ try:
|
||||
+ master1.ldif2db(bename=None, excludeSuffixes=None, encrypt=False, suffixes=[DEFAULT_SUFFIX], import_file=import_ldif)
|
||||
+ except:
|
||||
+ pass
|
||||
+ # master1.tasks.importLDIF(suffix=DEFAULT_SUFFIX, input_file=import_ldif, args={TASK_WAIT: True})
|
||||
+ master1.start()
|
||||
+ users = UserAccounts(master1, DEFAULT_SUFFIX, rdn='ou=Accounting')
|
||||
+
|
||||
+ u = users.create(properties=TEST_USER_PROPERTIES)
|
||||
+ u.set('userPassword', 'password')
|
||||
+
|
||||
+ binddn = u.dn
|
||||
+ bindpw = 'password'
|
||||
+
|
||||
+ # Now export them to master2
|
||||
+ master1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
|
||||
+
|
||||
+ # While that's happening try to bind as a user to master 2
|
||||
+ # This should trigger the referral code.
|
||||
+ for i in range(0, 100):
|
||||
+ conn = ldap.initialize(master2.toLDAPURL())
|
||||
+ conn.set_option(ldap.OPT_REFERRALS, False)
|
||||
+ try:
|
||||
+ conn.simple_bind_s(binddn, bindpw)
|
||||
+ conn.unbind_s()
|
||||
+ except ldap.REFERRAL:
|
||||
+ pass
|
||||
+
|
||||
+ # Done.
|
||||
+
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
|
||||
index 13a3c74..c2a862b 100644
|
||||
--- a/ldap/servers/slapd/fedse.c
|
||||
+++ b/ldap/servers/slapd/fedse.c
|
||||
@@ -1853,6 +1853,16 @@ setup_internal_backends(char *configdir)
|
||||
be_addsuffix(be,&monitor);
|
||||
be_addsuffix(be,&config);
|
||||
|
||||
+ /*
|
||||
+ * Now that the be's are in place, we can
|
||||
+ * setup the mapping tree.
|
||||
+ */
|
||||
+
|
||||
+ if (mapping_tree_init()) {
|
||||
+ slapi_log_err(SLAPI_LOG_EMERG, "setup_internal_backends", "Failed to init mapping tree\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
add_internal_entries();
|
||||
|
||||
add_easter_egg_entry();
|
||||
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
||||
index 552d54d..1d9afce 100644
|
||||
--- a/ldap/servers/slapd/main.c
|
||||
+++ b/ldap/servers/slapd/main.c
|
||||
@@ -1034,16 +1034,6 @@ main( int argc, char **argv)
|
||||
|
||||
ps_init_psearch_system(); /* must come before plugin_startall() */
|
||||
|
||||
- /* Initailize the mapping tree */
|
||||
-
|
||||
- if (mapping_tree_init())
|
||||
- {
|
||||
- slapi_log_err(SLAPI_LOG_EMERG, "main", "Failed to init mapping tree\n");
|
||||
- return_value = 1;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
-
|
||||
/* initialize UniqueID generator - must be done once backends are started
|
||||
and event queue is initialized but before plugins are started */
|
||||
/* Note: This DN is no need to be normalized. */
|
||||
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
|
||||
index 1b8d2d9..dfb6584 100644
|
||||
--- a/ldap/servers/slapd/mapping_tree.c
|
||||
+++ b/ldap/servers/slapd/mapping_tree.c
|
||||
@@ -88,13 +88,13 @@ struct mt_node
|
||||
* release backend lock
|
||||
*
|
||||
*/
|
||||
-static Slapi_RWLock *myLock; /* global lock on the mapping tree structures */
|
||||
+static Slapi_RWLock *myLock = NULL; /* global lock on the mapping tree structures */
|
||||
|
||||
|
||||
static mapping_tree_node *mapping_tree_root = NULL;
|
||||
-static int mapping_tree_inited = 0;
|
||||
-static int mapping_tree_freed = 0;
|
||||
-static int extension_type = -1; /* type returned from the factory */
|
||||
+static int32_t mapping_tree_inited = 0;
|
||||
+static int32_t mapping_tree_freed = 0;
|
||||
+static int extension_type = -1; /* type returned from the factory */
|
||||
|
||||
/* The different states a mapping tree node can be in. */
|
||||
#define MTN_DISABLED 0 /* The server acts like the node isn't there. */
|
||||
@@ -1659,22 +1659,24 @@ add_internal_mapping_tree_node(const char *subtree, Slapi_Backend *be, mapping_t
|
||||
{
|
||||
Slapi_DN *dn;
|
||||
mapping_tree_node *node;
|
||||
- backend ** be_list = (backend **) slapi_ch_malloc(sizeof(backend *));
|
||||
+ backend **be_list = (backend **)slapi_ch_malloc(sizeof(backend *));
|
||||
+ int *be_states = (int *)slapi_ch_malloc(sizeof(int));
|
||||
|
||||
be_list[0] = be;
|
||||
+ be_states[0] = SLAPI_BE_STATE_ON;
|
||||
|
||||
dn = slapi_sdn_new_dn_byval(subtree);
|
||||
- node= mapping_tree_node_new(
|
||||
- dn,
|
||||
- be_list,
|
||||
- NULL, /* backend_name */
|
||||
- NULL,
|
||||
- 1, /* number of backends at this node */
|
||||
- 1, /* size of backend list structure */
|
||||
- NULL, /* referral */
|
||||
- parent,
|
||||
- MTN_BACKEND,
|
||||
- 1, /* The config node is a private node.
|
||||
+ node = mapping_tree_node_new(
|
||||
+ dn,
|
||||
+ be_list,
|
||||
+ NULL, /* backend_name */
|
||||
+ be_states, /* be state */
|
||||
+ 1, /* number of backends at this node */
|
||||
+ 1, /* size of backend list structure */
|
||||
+ NULL, /* referral */
|
||||
+ parent,
|
||||
+ MTN_BACKEND,
|
||||
+ 1, /* The config node is a private node.
|
||||
* People can't see or change it. */
|
||||
NULL, NULL, NULL, 0); /* no distribution */
|
||||
return node;
|
||||
@@ -1722,17 +1724,20 @@ mapping_tree_init()
|
||||
|
||||
/* we call this function from a single thread, so it should be ok */
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
- /* shutdown has been detected */
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (mapping_tree_inited)
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
+ /* shutdown has been detected */
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
- /* ONREPL - I have moved this up because otherwise we can endup calling this
|
||||
+ /* ONREPL - I have moved this up because otherwise we can endup calling this
|
||||
* function recursively */
|
||||
+ if (myLock != NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ myLock = slapi_new_rwlock();
|
||||
+ slapi_rwlock_wrlock(myLock);
|
||||
|
||||
+ /* Should be fenced by the rwlock. */
|
||||
mapping_tree_inited = 1;
|
||||
|
||||
slapi_register_supported_control(MTN_CONTROL_USE_ONE_BACKEND_OID,
|
||||
@@ -1740,10 +1745,8 @@ mapping_tree_init()
|
||||
slapi_register_supported_control(MTN_CONTROL_USE_ONE_BACKEND_EXT_OID,
|
||||
SLAPI_OPERATION_SEARCH);
|
||||
|
||||
- myLock = slapi_new_rwlock();
|
||||
-
|
||||
- be= slapi_be_select_by_instance_name(DSE_BACKEND);
|
||||
- mapping_tree_root= add_internal_mapping_tree_node("", be, NULL);
|
||||
+ be = slapi_be_select_by_instance_name(DSE_BACKEND);
|
||||
+ mapping_tree_root = add_internal_mapping_tree_node("", be, NULL);
|
||||
|
||||
/* We also need to add the config and schema backends to the mapping tree.
|
||||
* They are special in that users will not know about it's node in the
|
||||
@@ -1757,17 +1760,23 @@ mapping_tree_init()
|
||||
node= add_internal_mapping_tree_node("cn=schema", be, mapping_tree_root);
|
||||
mapping_tree_node_add_child(mapping_tree_root, node);
|
||||
|
||||
- /*
|
||||
+ slapi_rwlock_unlock(myLock);
|
||||
+
|
||||
+ /*
|
||||
* Now we need to look under cn=mapping tree, cn=config to find the rest
|
||||
* of the mapping tree entries.
|
||||
* Builds the mapping tree from entries in the DIT. This function just
|
||||
* calls mapping_tree_node_get_children with the special case for the
|
||||
* root node.
|
||||
*/
|
||||
- if (mapping_tree_node_get_children(mapping_tree_root, 1))
|
||||
+
|
||||
+ if (mapping_tree_node_get_children(mapping_tree_root, 1)) {
|
||||
return -1;
|
||||
+ }
|
||||
|
||||
+ slapi_rwlock_wrlock(myLock);
|
||||
mtn_create_extension(mapping_tree_root);
|
||||
+ slapi_rwlock_unlock(myLock);
|
||||
|
||||
/* setup the dse callback functions for the ldbm instance config entry */
|
||||
{
|
||||
@@ -1840,8 +1849,8 @@ mapping_tree_free ()
|
||||
*/
|
||||
slapi_unregister_backend_state_change_all();
|
||||
/* recursively free tree nodes */
|
||||
- mtn_free_node (&mapping_tree_root);
|
||||
- mapping_tree_freed = 1;
|
||||
+ mtn_free_node(&mapping_tree_root);
|
||||
+ __atomic_store_4(&mapping_tree_freed, 1, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
/* This function returns the first node to parse when a search is done
|
||||
@@ -2083,14 +2092,12 @@ int slapi_dn_write_needs_referral(Slapi_DN *target_sdn, Slapi_Entry **referral)
|
||||
mapping_tree_node *target_node = NULL;
|
||||
int ret = 0;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if(!mapping_tree_inited) {
|
||||
- mapping_tree_init();
|
||||
- }
|
||||
+ PR_ASSERT(mapping_tree_inited == 1);
|
||||
|
||||
if (target_sdn) {
|
||||
mtn_lock();
|
||||
@@ -2157,8 +2164,8 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
||||
int fixup = 0;
|
||||
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
- /* shutdown detected */
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
+ /* shutdown detected */
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -2175,9 +2182,7 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
||||
target_sdn = operation_get_target_spec (op);
|
||||
fixup = operation_is_flag_set(op, OP_FLAG_TOMBSTONE_FIXUP);
|
||||
|
||||
- if(!mapping_tree_inited) {
|
||||
- mapping_tree_init();
|
||||
- }
|
||||
+ PR_ASSERT(mapping_tree_inited == 1);
|
||||
|
||||
be[0] = NULL;
|
||||
if (referral) {
|
||||
@@ -2188,8 +2193,9 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
|
||||
|
||||
/* Get the mapping tree node that is the best match for the target dn. */
|
||||
target_node = slapi_get_mapping_tree_node_by_dn(target_sdn);
|
||||
- if (target_node == NULL)
|
||||
+ if (target_node == NULL) {
|
||||
target_node = mapping_tree_root;
|
||||
+ }
|
||||
|
||||
/* The processing of the base scope root DSE search and all other LDAP operations on ""
|
||||
* will be transferred to the internal DSE backend
|
||||
@@ -2266,8 +2272,8 @@ int slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list,
|
||||
Slapi_DN *sdn = NULL;
|
||||
int flag_partial_result = 0;
|
||||
int op_type;
|
||||
-
|
||||
- if(mapping_tree_freed){
|
||||
+
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -2287,9 +2293,7 @@ int slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list,
|
||||
slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
|
||||
slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &scope);
|
||||
|
||||
- if(!mapping_tree_inited){
|
||||
- mapping_tree_init();
|
||||
- }
|
||||
+ PR_ASSERT(mapping_tree_inited == 1);
|
||||
|
||||
mtn_lock();
|
||||
|
||||
@@ -2448,8 +2452,8 @@ int slapi_mapping_tree_select_and_check(Slapi_PBlock *pb,char *newdn, Slapi_Back
|
||||
Slapi_Operation *op;
|
||||
int ret;
|
||||
int need_unlock = 0;
|
||||
-
|
||||
- if(mapping_tree_freed){
|
||||
+
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -2635,7 +2639,7 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
||||
int flag_stop = 0;
|
||||
struct slapi_componentid *cid = NULL;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shut down detected */
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
@@ -2719,21 +2723,22 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
||||
} else {
|
||||
/* This MTN has not been linked to its backend
|
||||
* instance yet. */
|
||||
- target_node->mtn_be[*index] =
|
||||
- slapi_be_select_by_instance_name(
|
||||
- target_node->mtn_backend_names[*index]);
|
||||
- *be = target_node->mtn_be[*index];
|
||||
- if(*be==NULL) {
|
||||
- slapi_log_err(SLAPI_LOG_BACKLDBM, "mtn_get_be",
|
||||
- "Warning: Mapping tree node entry for %s "
|
||||
- "point to an unknown backend : %s\n",
|
||||
- slapi_sdn_get_dn(target_node->mtn_subtree),
|
||||
- target_node->mtn_backend_names[*index]);
|
||||
- /* Well there's still not backend instance for
|
||||
- * this MTN, so let's have the default backend
|
||||
- * deal with this.
|
||||
- */
|
||||
- *be = defbackend_get_backend();
|
||||
+ /* WARNING: internal memory dse backends don't provide NAMES */
|
||||
+ if (target_node->mtn_backend_names != NULL) {
|
||||
+ target_node->mtn_be[*index] = slapi_be_select_by_instance_name(target_node->mtn_backend_names[*index]);
|
||||
+ *be = target_node->mtn_be[*index];
|
||||
+ if (*be == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_BACKLDBM, "mtn_get_be",
|
||||
+ "Warning: Mapping tree node entry for %s "
|
||||
+ "point to an unknown backend : %s\n",
|
||||
+ slapi_sdn_get_dn(target_node->mtn_subtree),
|
||||
+ target_node->mtn_backend_names[*index]);
|
||||
+ /* Well there's still not backend instance for
|
||||
+ * this MTN, so let's have the default backend
|
||||
+ * deal with this.
|
||||
+ */
|
||||
+ *be = defbackend_get_backend();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2745,10 +2750,11 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
|
||||
result = LDAP_OPERATIONS_ERROR;
|
||||
*be = defbackend_get_backend();
|
||||
}
|
||||
- if (flag_stop)
|
||||
+ if (flag_stop) {
|
||||
*index = SLAPI_BE_NO_BACKEND;
|
||||
- else
|
||||
+ } else {
|
||||
(*index)++;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2822,7 +2828,7 @@ static mapping_tree_node *best_matching_child(mapping_tree_node *parent,
|
||||
mapping_tree_node *highest_match_node = NULL;
|
||||
mapping_tree_node *current;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
@@ -2849,7 +2855,7 @@ mtn_get_mapping_tree_node_by_entry(mapping_tree_node* node, const Slapi_DN *dn)
|
||||
{
|
||||
mapping_tree_node *found_node = NULL;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
@@ -2895,7 +2901,7 @@ slapi_get_mapping_tree_node_by_dn(const Slapi_DN *dn)
|
||||
mapping_tree_node *current_best_match = mapping_tree_root;
|
||||
mapping_tree_node *next_best_match = mapping_tree_root;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
@@ -2929,7 +2935,7 @@ get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name)
|
||||
int i;
|
||||
mapping_tree_node *found_node = NULL;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
@@ -2980,7 +2986,7 @@ slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
|
||||
{
|
||||
char *dn = NULL;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
@@ -3007,7 +3013,7 @@ slapi_get_mapping_tree_node_configsdn (const Slapi_DN *root)
|
||||
char *dn = NULL;
|
||||
Slapi_DN *sdn = NULL;
|
||||
|
||||
- if(mapping_tree_freed){
|
||||
+ if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) {
|
||||
/* shutdown detected */
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/pw_verify.c b/ldap/servers/slapd/pw_verify.c
|
||||
index cb182ed..1f0c18a 100644
|
||||
--- a/ldap/servers/slapd/pw_verify.c
|
||||
+++ b/ldap/servers/slapd/pw_verify.c
|
||||
@@ -58,12 +58,14 @@ pw_verify_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
int rc = SLAPI_BIND_SUCCESS;
|
||||
Slapi_Backend *be = NULL;
|
||||
|
||||
- if (slapi_mapping_tree_select(pb, &be, referral, NULL, 0) != LDAP_SUCCESS) {
|
||||
+ int mt_result = slapi_mapping_tree_select(pb, &be, referral, NULL, 0);
|
||||
+ if (mt_result != LDAP_SUCCESS) {
|
||||
return SLAPI_BIND_NO_BACKEND;
|
||||
}
|
||||
|
||||
if (*referral) {
|
||||
- slapi_be_Unlock(be);
|
||||
+ /* If we have a referral, this is NULL */
|
||||
+ PR_ASSERT(be == NULL);
|
||||
return SLAPI_BIND_REFERRAL;
|
||||
}
|
||||
|
||||
@@ -128,7 +130,7 @@ pw_validate_be_dn(Slapi_PBlock *pb, Slapi_Entry **referral)
|
||||
}
|
||||
|
||||
if (*referral) {
|
||||
- slapi_be_Unlock(be);
|
||||
+ PR_ASSERT(be == NULL);
|
||||
return SLAPI_BIND_REFERRAL;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
1041
SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch
Normal file
1041
SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,25 @@
|
|||
From c9817ebe42a97ac7df155582957927b4d1d08c5f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 14:55:14 -0400
|
||||
Subject: [PATCH] Ticket 49330 - Add endian header file
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 67217af..163db7d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -39,7 +39,7 @@ AC_PROG_LIBTOOL
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
-AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/file.h sys/socket.h sys/time.h syslog.h unistd.h inttypes.h mntent.h sys/sysinfo.h])
|
||||
+AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/file.h sys/socket.h sys/time.h syslog.h unistd.h mntent.h sys/sysinfo.h sys/endian.h endian.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STAT
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
From bbe3403a88f9adecbd5d4187ceeb080fb51d9d14 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Wed, 31 May 2017 11:15:13 -0400
|
||||
Subject: [PATCH] Ticket 49257 - only register modify callbacks
|
||||
|
||||
Bug Description: Regression. In the previous fix we called
|
||||
ldbm_instance_config_load_dse_info() to register all
|
||||
the dse preop callbacks. Previously this was only done
|
||||
when creating an instance. It was not designed to be
|
||||
used outside of that context, and it caused error 53's
|
||||
when trying to add a backend after instance creation.
|
||||
|
||||
Fix Description: Just register the "modify" DSE preop callbacks.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49257
|
||||
|
||||
Reviewed by: ?
|
||||
|
||||
(cherry picked from commit 75a32a8829297a5cab303590d049f581740cf87e)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/instance.c | 12 +++---------
|
||||
ldap/servers/slapd/back-ldbm/ldbm_config.h | 2 +-
|
||||
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 13 +++++++++++++
|
||||
3 files changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
index 8b38644..f067d22 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/instance.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/instance.c
|
||||
@@ -305,15 +305,9 @@ ldbm_instance_startall(struct ldbminfo *li)
|
||||
if (rc1 != 0) {
|
||||
rc = rc1;
|
||||
} else {
|
||||
- if(ldbm_instance_config_load_dse_info(inst) != 0){
|
||||
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_startall",
|
||||
- "Loading database instance configuration failed for (%s)\n",
|
||||
- inst->inst_name);
|
||||
- rc = -1;
|
||||
- } else {
|
||||
- vlv_init(inst);
|
||||
- slapi_mtn_be_started(inst->inst_be);
|
||||
- }
|
||||
+ ldbm_instance_register_modify_callback(inst);
|
||||
+ vlv_init(inst);
|
||||
+ slapi_mtn_be_started(inst->inst_be);
|
||||
}
|
||||
inst_obj = objset_next_obj(li->li_instance_set, inst_obj);
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.h b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
index ddec3a8..ea59739 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.h
|
||||
@@ -157,6 +157,6 @@ int
|
||||
ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e);
|
||||
int ldbm_instance_create_default_user_indexes(ldbm_instance *inst);
|
||||
void ldbm_config_destroy(struct ldbminfo *li);
|
||||
-
|
||||
+void ldbm_instance_register_modify_callback(ldbm_instance *inst);
|
||||
|
||||
#endif /* _LDBM_CONFIG_H_ */
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
index 49a6cac..8fb4119 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
|
||||
@@ -554,6 +554,19 @@ static int ldbm_instance_deny_config(Slapi_PBlock *pb, Slapi_Entry *e,
|
||||
return SLAPI_DSE_CALLBACK_ERROR;
|
||||
}
|
||||
|
||||
+void
|
||||
+ldbm_instance_register_modify_callback(ldbm_instance *inst)
|
||||
+{
|
||||
+ struct ldbminfo *li = inst->inst_li;
|
||||
+ char *dn = NULL;
|
||||
+
|
||||
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
|
||||
+ inst->inst_name, li->li_plugin->plg_name);
|
||||
+ slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
|
||||
+ LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
+ ldbm_instance_modify_config_entry_callback, (void *) inst);
|
||||
+ slapi_ch_free_string(&dn);
|
||||
+}
|
||||
/* Reads in any config information held in the dse for the given
|
||||
* entry. Creates dse entries used to configure the given instance
|
||||
* if they don't already exist. Registers dse callback functions to
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
From 28529671057c95327a35c326ee99fcafccad9de9 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 14 Jun 2017 18:36:55 +0200
|
||||
Subject: [PATCH] Ticket 49291 - slapi_search_internal_callback_pb may SIGSEV
|
||||
if related pblock has not operation set
|
||||
|
||||
Bug Description:
|
||||
if slapi_search_internal_set_pb is called with an invalid (NULL) base, the pblock should not
|
||||
be used to call send_ldap_result. If it is, the send_ldap_result trying to derefence the
|
||||
operation pointer will crash
|
||||
|
||||
Fix Description:
|
||||
Check that the operation is set before derefencing it
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49291
|
||||
|
||||
Reviewed by: Mark Reynolds
|
||||
|
||||
Platforms tested: F23
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/result.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
||||
index 56257c3..f3016ca 100644
|
||||
--- a/ldap/servers/slapd/result.c
|
||||
+++ b/ldap/servers/slapd/result.c
|
||||
@@ -350,6 +350,11 @@ send_ldap_result_ext(
|
||||
slapi_pblock_get (pb, SLAPI_BIND_METHOD, &bind_method);
|
||||
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
|
||||
|
||||
+ if (operation == NULL) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "send_ldap_result_ext", "No operation found: slapi_search_internal_set_pb was incomplete (invalid 'base' ?)\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (operation->o_status == SLAPI_OP_STATUS_RESULT_SENT) {
|
||||
return; /* result already sent */
|
||||
}
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 1ec56936d29985a55f9529c1ea3e71056557b3ff Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 1 Sep 2017 09:24:55 -0400
|
||||
Subject: [PATCH] Ticket 49370 - local password policies should use the same
|
||||
defaults as the global policy
|
||||
|
||||
Description: When a local password policy (subtree/user) is created it does not use
|
||||
the same defaults as the global policy. This causes inconsistent behavior.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49370
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/pw.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
|
||||
index 378d148..19a863a 100644
|
||||
--- a/ldap/servers/slapd/pw.c
|
||||
+++ b/ldap/servers/slapd/pw.c
|
||||
@@ -1768,6 +1768,27 @@ 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_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH;
|
||||
+ 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;
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From af59afa03296160577e419257772d5319796a992 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 08:32:11 -0400
|
||||
Subject: [PATCH] Ticket 49380 - Crash when adding invalid replication
|
||||
agreement
|
||||
|
||||
Bug Description: If you add a replication agreement with an invalid "replicaEnabled" value
|
||||
the server crashes when freeing the replica schedule. This is because the
|
||||
schedule never gets allocated before the rror conidtion is hit, and then
|
||||
it get dereferenced.
|
||||
|
||||
Fix Description: Check for a NULL schedule before trying to destroy it.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49380
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl5_schedule.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_schedule.c b/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
index 60ee6f2..4572e63 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_schedule.c
|
||||
@@ -130,6 +130,10 @@ schedule_destroy(Schedule *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
+ if (s == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* unschedule update window event if exists */
|
||||
unschedule_window_state_change_event (s);
|
||||
|
||||
@@ -177,11 +181,15 @@ free_schedule_list(schedule_item **schedule_list)
|
||||
int
|
||||
schedule_set(Schedule *sch, Slapi_Attr *attr)
|
||||
{
|
||||
- int return_value;
|
||||
+ int return_value = -1;
|
||||
schedule_item *si = NULL;
|
||||
schedule_item *new_schedule_list = NULL;
|
||||
int valid = 1;
|
||||
|
||||
+ if (sch == NULL) {
|
||||
+ return return_value;
|
||||
+ }
|
||||
+
|
||||
if (NULL != attr)
|
||||
{
|
||||
int ind;
|
||||
--
|
||||
2.9.5
|
||||
|
81
SOURCES/0068-Ticket-49380-Add-CI-test.patch
Normal file
81
SOURCES/0068-Ticket-49380-Add-CI-test.patch
Normal file
|
@ -0,0 +1,81 @@
|
|||
From d336e3558655d44f8ba797392af882e33d492958 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 14:15:25 -0400
|
||||
Subject: [PATCH] Ticket 49380 - Add CI test
|
||||
|
||||
Description: Add test to verify invalid agreement is rejected, and it
|
||||
does not cause a crash
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49380
|
||||
|
||||
Reviewed by: spichugi(Thanks!)
|
||||
|
||||
(cherry picked from commit 02d76b61489f105f81d72d4f3848e2444463289b)
|
||||
---
|
||||
.../tests/suites/replication/acceptance_test.py | 43 ++++++++++++++++++++++
|
||||
1 file changed, 43 insertions(+)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/replication/acceptance_test.py b/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
index e6f2ef7..2f8b180 100644
|
||||
--- a/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
+++ b/dirsrvtests/tests/suites/replication/acceptance_test.py
|
||||
@@ -3,6 +3,12 @@ from lib389.tasks import *
|
||||
from lib389.utils import *
|
||||
from lib389.topologies import topology_m4 as topo
|
||||
|
||||
+from lib389._constants import (BACKEND_NAME, DEFAULT_SUFFIX, LOG_REPLICA, REPLICA_RUV_FILTER,
|
||||
+ ReplicaRole, REPLICATION_BIND_DN, REPLICATION_BIND_PW,
|
||||
+ REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT, defaultProperties,
|
||||
+ RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD, RA_TRANSPORT_PROT,
|
||||
+ DN_DM, PASSWORD, LOG_DEFAULT, RA_ENABLED, RA_SCHEDULE)
|
||||
+
|
||||
TEST_ENTRY_NAME = 'mmrepl_test'
|
||||
TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX)
|
||||
|
||||
@@ -193,6 +199,43 @@ def test_modrdn_entry(topo, test_entry, delold):
|
||||
topo.ms["master1"].delete_s(newrdn_dn)
|
||||
|
||||
|
||||
+def test_invalid_agmt(topo_m4):
|
||||
+ """Test adding that an invalid agreement is properly rejected and does not crash the server
|
||||
+
|
||||
+ :id: 6c3b2a7e-edcd-4327-a003-6bd878ff722b
|
||||
+ :setup: MMR with four masters
|
||||
+ :steps:
|
||||
+ 1. Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
|
||||
+ 2. Verify the server is still running
|
||||
+ :expectedresults:
|
||||
+ 1. Invalid repl agreement should be rejected
|
||||
+ 2. Server should be still running
|
||||
+ """
|
||||
+ m1 = topo_m4.ms["master1"]
|
||||
+
|
||||
+ # Add invalid agreement (nsds5ReplicaEnabled set to invalid value)
|
||||
+ AGMT_DN = 'cn=whatever,cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config'
|
||||
+ try:
|
||||
+ invalid_props = {RA_ENABLED: 'True', # Invalid value
|
||||
+ RA_SCHEDULE: '0001-2359 0123456'}
|
||||
+ m1.agreement.create(suffix=DEFAULT_SUFFIX, host='localhost', port=389, properties=invalid_props)
|
||||
+ except ldap.UNWILLING_TO_PERFORM:
|
||||
+ m1.log.info('Invalid repl agreement correctly rejected')
|
||||
+ except ldap.LDAPError as e:
|
||||
+ m1.log.fatal('Got unexpected error adding invalid agreement: ' + str(e))
|
||||
+ assert False
|
||||
+ else:
|
||||
+ m1.log.fatal('Invalid agreement was incorrectly accepted by the server')
|
||||
+ assert False
|
||||
+
|
||||
+ # Verify the server is still running
|
||||
+ try:
|
||||
+ m1.simple_bind_s(DN_DM, PASSWORD)
|
||||
+ except ldap.LDAPError as e:
|
||||
+ m1.log.fatal('Failed to bind: ' + str(e))
|
||||
+ assert False
|
||||
+
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
# Run isolated
|
||||
# -s for DEBUG mode
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,610 @@
|
|||
From 3ab8a78cd27cc8d2ad7a2b322a4fe73c43a3db08 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Thu, 14 Sep 2017 15:47:53 -0400
|
||||
Subject: [PATCH] Ticket 49327 - password expired control not sent during grace
|
||||
logins
|
||||
|
||||
Bug Description: When a password is expired, but within the grace login limit,
|
||||
we should still send the expired control even though we allowed
|
||||
the bind.
|
||||
|
||||
Fix Description: new_new_passwd() returned a variety of result codes that required
|
||||
the caller to set the response controls. This was hard to read and
|
||||
process. Instead I added all the controls inside the function, and
|
||||
return success or failure to the caller.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49327
|
||||
|
||||
Reviewed by: gparente & tbordaz (Thanks!!)
|
||||
|
||||
(cherry picked from commit fbd32c4e27af9f331ee3a42dec944895a6efe2ad)
|
||||
---
|
||||
ldap/servers/plugins/replication/repl_extop.c | 5 +-
|
||||
ldap/servers/slapd/bind.c | 18 +-
|
||||
ldap/servers/slapd/proto-slap.h | 3 +-
|
||||
ldap/servers/slapd/pw_mgmt.c | 453 +++++++++++++-------------
|
||||
ldap/servers/slapd/saslbind.c | 20 +-
|
||||
5 files changed, 238 insertions(+), 261 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
||||
index a39d918..96ad7dd 100644
|
||||
--- a/ldap/servers/plugins/replication/repl_extop.c
|
||||
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
||||
@@ -1173,8 +1173,9 @@ send_response:
|
||||
* On the supplier, we need to close the connection so
|
||||
* that the RA will restart a new session in a clear state
|
||||
*/
|
||||
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
- "already acquired replica: disconnect conn=%d\n", connid);
|
||||
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
+ "multimaster_extop_StartNSDS50ReplicationRequest - "
|
||||
+ "already acquired replica: disconnect conn=%" PRIu64 "\n", connid);
|
||||
slapi_disconnect_server(conn);
|
||||
|
||||
}
|
||||
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
||||
index d6c7668..e6cad7f 100644
|
||||
--- a/ldap/servers/slapd/bind.c
|
||||
+++ b/ldap/servers/slapd/bind.c
|
||||
@@ -673,8 +673,7 @@ do_bind( Slapi_PBlock *pb )
|
||||
slapi_entry_free(referral);
|
||||
goto free_and_return;
|
||||
} else if (auto_bind || rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
|
||||
- long t;
|
||||
- char* authtype = NULL;
|
||||
+ char *authtype = NULL;
|
||||
/* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */
|
||||
if(auto_bind) {
|
||||
rc = SLAPI_BIND_SUCCESS;
|
||||
@@ -761,19 +760,8 @@ do_bind( Slapi_PBlock *pb )
|
||||
slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
|
||||
NULL, NULL, NULL, bind_target_entry);
|
||||
if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
||||
- /* check if need new password before sending
|
||||
- the bind success result */
|
||||
- myrc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested);
|
||||
- switch (myrc) {
|
||||
- case 1:
|
||||
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- break;
|
||||
- case 2:
|
||||
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
+ /* check if need new password before sending the bind success result */
|
||||
+ myrc = need_new_pw(pb, bind_target_entry, pw_response_requested);
|
||||
}
|
||||
}
|
||||
if (auth_response_requested) {
|
||||
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||
index 9696ead..0ba61d7 100644
|
||||
--- a/ldap/servers/slapd/proto-slap.h
|
||||
+++ b/ldap/servers/slapd/proto-slap.h
|
||||
@@ -972,7 +972,7 @@ int plugin_call_acl_verify_syntax ( Slapi_PBlock *pb, Slapi_Entry *e, char **err
|
||||
* pw_mgmt.c
|
||||
*/
|
||||
void pw_init( void );
|
||||
-int need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req );
|
||||
+int need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req);
|
||||
int update_pw_info( Slapi_PBlock *pb , char *old_pw );
|
||||
int check_pw_syntax( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals,
|
||||
char **old_pw, Slapi_Entry *e, int mod_op );
|
||||
@@ -982,7 +982,6 @@ void get_old_pw( Slapi_PBlock *pb, const Slapi_DN *sdn, char **old_pw);
|
||||
int check_account_lock( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req, int account_inactivation_only /*no wire/no pw policy*/);
|
||||
int check_pw_minage( Slapi_PBlock *pb, const Slapi_DN *sdn, struct berval **vals) ;
|
||||
void add_password_attrs( Slapi_PBlock *pb, Operation *op, Slapi_Entry *e );
|
||||
-
|
||||
int add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e);
|
||||
|
||||
/*
|
||||
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
|
||||
index 7252c08..b06e3f1 100644
|
||||
--- a/ldap/servers/slapd/pw_mgmt.c
|
||||
+++ b/ldap/servers/slapd/pw_mgmt.c
|
||||
@@ -22,234 +22,239 @@
|
||||
/* prototypes */
|
||||
/****************************************************************************/
|
||||
|
||||
-/* need_new_pw() is called when non rootdn bind operation succeeds with authentication */
|
||||
+/*
|
||||
+ * need_new_pw() is called when non rootdn bind operation succeeds with authentication
|
||||
+ *
|
||||
+ * Return 0 - password is okay
|
||||
+ * Return -1 - password is expired, abort bind
|
||||
+ */
|
||||
int
|
||||
-need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req )
|
||||
+need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req)
|
||||
{
|
||||
- time_t cur_time, pw_exp_date;
|
||||
- Slapi_Mods smods;
|
||||
- double diff_t = 0;
|
||||
- char *cur_time_str = NULL;
|
||||
- char *passwordExpirationTime = NULL;
|
||||
- char *timestring;
|
||||
- char *dn;
|
||||
- const Slapi_DN *sdn;
|
||||
- passwdPolicy *pwpolicy = NULL;
|
||||
- int pwdGraceUserTime = 0;
|
||||
- char graceUserTime[8];
|
||||
-
|
||||
- if (NULL == e) {
|
||||
- return (-1);
|
||||
- }
|
||||
- slapi_mods_init (&smods, 0);
|
||||
- sdn = slapi_entry_get_sdn_const( e );
|
||||
- dn = slapi_entry_get_ndn( e );
|
||||
- pwpolicy = new_passwdPolicy(pb, dn);
|
||||
-
|
||||
- /* after the user binds with authentication, clear the retry count */
|
||||
- if ( pwpolicy->pw_lockout == 1)
|
||||
- {
|
||||
- if(slapi_entry_attr_get_int( e, "passwordRetryCount") > 0)
|
||||
- {
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- cur_time = current_time();
|
||||
-
|
||||
- /* get passwordExpirationTime attribute */
|
||||
- passwordExpirationTime= slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
||||
-
|
||||
- if (passwordExpirationTime == NULL)
|
||||
- {
|
||||
- /* password expiration date is not set.
|
||||
- * This is ok for data that has been loaded via ldif2ldbm
|
||||
- * Set expiration time if needed,
|
||||
- * don't do further checking and return 0 */
|
||||
- if (pwpolicy->pw_exp == 1) {
|
||||
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
||||
-
|
||||
- timestring = format_genTime (pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- } else if (pwpolicy->pw_lockout == 1) {
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- }
|
||||
- slapi_mods_done(&smods);
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- pw_exp_date = parse_genTime(passwordExpirationTime);
|
||||
-
|
||||
- slapi_ch_free_string(&passwordExpirationTime);
|
||||
-
|
||||
- /* Check if password has been reset */
|
||||
- if ( pw_exp_date == NO_TIME ) {
|
||||
-
|
||||
- /* check if changing password is required */
|
||||
- if ( pwpolicy->pw_must_change ) {
|
||||
- /* set c_needpw for this connection to be true. this client
|
||||
- now can only change its own password */
|
||||
- pb->pb_conn->c_needpw = 1;
|
||||
- *t=0;
|
||||
- /* We need to include "changeafterreset" error in
|
||||
- * passwordpolicy response control. So, we will not be
|
||||
- * done here. We remember this scenario by (c_needpw=1)
|
||||
- * and check it before sending the control from various
|
||||
- * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
||||
- * as the return value used to be (1).
|
||||
- */
|
||||
- goto skip;
|
||||
- }
|
||||
- /* Mark that first login occured */
|
||||
- pw_exp_date = NOT_FIRST_TIME;
|
||||
- timestring = format_genTime(pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
- }
|
||||
+ time_t cur_time, pw_exp_date;
|
||||
+ Slapi_Mods smods;
|
||||
+ double diff_t = 0;
|
||||
+ char *cur_time_str = NULL;
|
||||
+ char *passwordExpirationTime = NULL;
|
||||
+ char *timestring;
|
||||
+ char *dn;
|
||||
+ const Slapi_DN *sdn;
|
||||
+ passwdPolicy *pwpolicy = NULL;
|
||||
+ int pwdGraceUserTime = 0;
|
||||
+ char graceUserTime[16] = {0};
|
||||
+ Connection *pb_conn = NULL;
|
||||
+ long t;
|
||||
+
|
||||
+ if (NULL == e) {
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ slapi_mods_init(&smods, 0);
|
||||
+ sdn = slapi_entry_get_sdn_const(e);
|
||||
+ dn = slapi_entry_get_ndn(e);
|
||||
+ pwpolicy = new_passwdPolicy(pb, dn);
|
||||
+
|
||||
+ /* after the user binds with authentication, clear the retry count */
|
||||
+ if (pwpolicy->pw_lockout == 1) {
|
||||
+ if (slapi_entry_attr_get_int(e, "passwordRetryCount") > 0) {
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cur_time = current_time();
|
||||
+
|
||||
+ /* get passwordExpirationTime attribute */
|
||||
+ passwordExpirationTime = slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
||||
+
|
||||
+ if (passwordExpirationTime == NULL) {
|
||||
+ /* password expiration date is not set.
|
||||
+ * This is ok for data that has been loaded via ldif2ldbm
|
||||
+ * Set expiration time if needed,
|
||||
+ * don't do further checking and return 0 */
|
||||
+ if (pwpolicy->pw_exp == 1) {
|
||||
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
||||
+
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ } else if (pwpolicy->pw_lockout == 1) {
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ }
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ pw_exp_date = parse_genTime(passwordExpirationTime);
|
||||
+
|
||||
+ slapi_ch_free_string(&passwordExpirationTime);
|
||||
+
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+
|
||||
+ /* Check if password has been reset */
|
||||
+ if (pw_exp_date == NO_TIME) {
|
||||
+
|
||||
+ /* check if changing password is required */
|
||||
+ if (pwpolicy->pw_must_change) {
|
||||
+ /* set c_needpw for this connection to be true. this client
|
||||
+ now can only change its own password */
|
||||
+ pb_conn->c_needpw = 1;
|
||||
+ t = 0;
|
||||
+ /* We need to include "changeafterreset" error in
|
||||
+ * passwordpolicy response control. So, we will not be
|
||||
+ * done here. We remember this scenario by (c_needpw=1)
|
||||
+ * and check it before sending the control from various
|
||||
+ * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
||||
+ * as the return value used to be (1).
|
||||
+ */
|
||||
+ goto skip;
|
||||
+ }
|
||||
+ /* Mark that first login occured */
|
||||
+ pw_exp_date = NOT_FIRST_TIME;
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+ }
|
||||
|
||||
skip:
|
||||
- /* if password never expires, don't need to go on; return 0 */
|
||||
- if ( pwpolicy->pw_exp == 0 ) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- if (pwresponse_req) {
|
||||
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET );
|
||||
- }
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- /* check if password expired. If so, abort bind. */
|
||||
- cur_time_str = format_genTime ( cur_time );
|
||||
- if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
||||
- (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
||||
- slapi_ch_free_string(&cur_time_str); /* only need this above */
|
||||
- /* password has expired. Check the value of
|
||||
- * passwordGraceUserTime and compare it
|
||||
- * against the value of passwordGraceLimit */
|
||||
- pwdGraceUserTime = slapi_entry_attr_get_int( e, "passwordGraceUserTime");
|
||||
- if ( pwpolicy->pw_gracelimit > pwdGraceUserTime ) {
|
||||
- pwdGraceUserTime++;
|
||||
- sprintf ( graceUserTime, "%d", pwdGraceUserTime );
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
||||
- "passwordGraceUserTime", graceUserTime);
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- if (pwresponse_req) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_pwpolicy_make_response_control( pb, -1,
|
||||
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
- LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
- } else {
|
||||
- slapi_pwpolicy_make_response_control( pb, -1,
|
||||
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
- -1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- return ( 0 );
|
||||
- }
|
||||
-
|
||||
- /* password expired and user exceeded limit of grace attemps.
|
||||
- * Send result and also the control */
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- if (pwresponse_req) {
|
||||
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED );
|
||||
- }
|
||||
- slapi_send_ldap_result ( pb, LDAP_INVALID_CREDENTIALS, NULL,
|
||||
- "password expired!", 0, NULL );
|
||||
-
|
||||
- /* abort bind */
|
||||
- /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
||||
- pb->pb_op->o_tag are not right but I don't see
|
||||
- do_unbind() checking for those. We might need to
|
||||
- create a pb for unbind operation. Also do_unbind calls
|
||||
- pre and post ops. Maybe we don't want to call them */
|
||||
- if (pb->pb_conn && (LDAP_VERSION2 == pb->pb_conn->c_ldapversion)) {
|
||||
- /* We close the connection only with LDAPv2 connections */
|
||||
- disconnect_server( pb->pb_conn, pb->pb_op->o_connid,
|
||||
- pb->pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
||||
- }
|
||||
- /* Apply current modifications */
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- return (-1);
|
||||
- }
|
||||
- slapi_ch_free((void **) &cur_time_str );
|
||||
-
|
||||
- /* check if password is going to expire within "passwordWarning" */
|
||||
- /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
||||
- * we must send warning first and this changes the expiration time.
|
||||
- * This is done just below since diff_t is 0
|
||||
- */
|
||||
- if ( diff_t <= pwpolicy->pw_warning ) {
|
||||
- int pw_exp_warned = 0;
|
||||
-
|
||||
- pw_exp_warned = slapi_entry_attr_get_int( e, "passwordExpWarned");
|
||||
- if ( !pw_exp_warned ){
|
||||
- /* first time send out a warning */
|
||||
- /* reset the expiration time to current + warning time
|
||||
- * and set passwordExpWarned to true
|
||||
- */
|
||||
- if (pb->pb_conn->c_needpw != 1) {
|
||||
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
||||
- }
|
||||
-
|
||||
- timestring = format_genTime(pw_exp_date);
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
- slapi_ch_free_string(×tring);
|
||||
-
|
||||
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
||||
-
|
||||
- *t = pwpolicy->pw_warning;
|
||||
-
|
||||
- } else {
|
||||
- *t = (long)diff_t; /* jcm: had to cast double to long */
|
||||
- }
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- if (pwresponse_req) {
|
||||
- /* check for "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
||||
- LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
- } else {
|
||||
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
||||
- -1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- return (2);
|
||||
- } else {
|
||||
- if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
||||
- slapi_pwpolicy_make_response_control( pb, diff_t, -1, -1);
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- pw_apply_mods(sdn, &smods);
|
||||
- slapi_mods_done(&smods);
|
||||
- /* Leftover from "changeafterreset" condition */
|
||||
- if (pb->pb_conn->c_needpw == 1) {
|
||||
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- }
|
||||
- /* passes checking, return 0 */
|
||||
- return( 0 );
|
||||
+ /* if password never expires, don't need to go on; return 0 */
|
||||
+ if (pwpolicy->pw_exp == 0) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ if (pwresponse_req) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ }
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ }
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* check if password expired. If so, abort bind. */
|
||||
+ cur_time_str = format_genTime(cur_time);
|
||||
+ if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
||||
+ (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
||||
+ slapi_ch_free_string(&cur_time_str); /* only need this above */
|
||||
+ /* password has expired. Check the value of
|
||||
+ * passwordGraceUserTime and compare it
|
||||
+ * against the value of passwordGraceLimit */
|
||||
+ pwdGraceUserTime = slapi_entry_attr_get_int(e, "passwordGraceUserTime");
|
||||
+ if (pwpolicy->pw_gracelimit > pwdGraceUserTime) {
|
||||
+ pwdGraceUserTime++;
|
||||
+ sprintf(graceUserTime, "%d", pwdGraceUserTime);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
||||
+ "passwordGraceUserTime", graceUserTime);
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ if (pwresponse_req) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1,
|
||||
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
+ LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ } else {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1,
|
||||
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
||||
+ -1);
|
||||
+ }
|
||||
+ }
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* password expired and user exceeded limit of grace attemps.
|
||||
+ * Send result and also the control */
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ if (pwresponse_req) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
|
||||
+ }
|
||||
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
|
||||
+ "password expired!", 0, NULL);
|
||||
+
|
||||
+ /* abort bind */
|
||||
+ /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
||||
+ pb->pb_op->o_tag are not right but I don't see
|
||||
+ do_unbind() checking for those. We might need to
|
||||
+ create a pb for unbind operation. Also do_unbind calls
|
||||
+ pre and post ops. Maybe we don't want to call them */
|
||||
+ if (pb_conn && (LDAP_VERSION2 == pb_conn->c_ldapversion)) {
|
||||
+ Operation *pb_op = NULL;
|
||||
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
||||
+ /* We close the connection only with LDAPv2 connections */
|
||||
+ disconnect_server(pb_conn, pb_op->o_connid,
|
||||
+ pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
||||
+ }
|
||||
+ /* Apply current modifications */
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ slapi_ch_free((void **)&cur_time_str);
|
||||
+
|
||||
+ /* check if password is going to expire within "passwordWarning" */
|
||||
+ /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
||||
+ * we must send warning first and this changes the expiration time.
|
||||
+ * This is done just below since diff_t is 0
|
||||
+ */
|
||||
+ if (diff_t <= pwpolicy->pw_warning) {
|
||||
+ int pw_exp_warned = 0;
|
||||
+
|
||||
+ pw_exp_warned = slapi_entry_attr_get_int(e, "passwordExpWarned");
|
||||
+ if (!pw_exp_warned) {
|
||||
+ /* first time send out a warning */
|
||||
+ /* reset the expiration time to current + warning time
|
||||
+ * and set passwordExpWarned to true
|
||||
+ */
|
||||
+ if (pb_conn->c_needpw != 1) {
|
||||
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
||||
+ }
|
||||
+
|
||||
+ timestring = format_genTime(pw_exp_date);
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
||||
+ slapi_ch_free_string(×tring);
|
||||
+
|
||||
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
||||
+
|
||||
+ t = pwpolicy->pw_warning;
|
||||
+
|
||||
+ } else {
|
||||
+ t = (long)diff_t; /* jcm: had to cast double to long */
|
||||
+ }
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ if (pwresponse_req) {
|
||||
+ /* check for "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, t, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
||||
+ } else {
|
||||
+ slapi_pwpolicy_make_response_control(pb, t, -1, -1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ } else {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
+ }
|
||||
+ return (0);
|
||||
+ } else {
|
||||
+ if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
||||
+ slapi_pwpolicy_make_response_control(pb, diff_t, -1, -1);
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pw_apply_mods(sdn, &smods);
|
||||
+ slapi_mods_done(&smods);
|
||||
+ /* Leftover from "changeafterreset" condition */
|
||||
+ if (pb_conn->c_needpw == 1) {
|
||||
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
+ }
|
||||
+ /* passes checking, return 0 */
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
/* Called once from main */
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index dd0c4fb..134f5aa 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -859,7 +859,6 @@ ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
|
||||
void ids_sasl_check_bind(Slapi_PBlock *pb)
|
||||
{
|
||||
int rc, isroot;
|
||||
- long t;
|
||||
sasl_conn_t *sasl_conn;
|
||||
struct propctx *propctx;
|
||||
sasl_ssf_t *ssfp;
|
||||
@@ -1096,23 +1095,8 @@ sasl_check_result:
|
||||
set_db_default_result_handlers(pb);
|
||||
|
||||
/* check password expiry */
|
||||
- if (!isroot) {
|
||||
- int pwrc;
|
||||
-
|
||||
- pwrc = need_new_pw(pb, &t, bind_target_entry, pwresponse_requested);
|
||||
-
|
||||
- switch (pwrc) {
|
||||
- case 1:
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
||||
- break;
|
||||
- case 2:
|
||||
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
||||
- break;
|
||||
- case -1:
|
||||
- goto out;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
+ if (!isroot && need_new_pw(pb, bind_target_entry, pwresponse_requested) == -1) {
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* attach the sasl data */
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,439 @@
|
|||
From 8a7b47602acc910d2f64439b81af3299b60359c8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 10:35:20 -0400
|
||||
Subject: [PATCH] Ticket 49379 - Allowed sasl mapping requires restart
|
||||
|
||||
Bug Description: If allowed sasl mechanisms are configured, and the server is
|
||||
restarted, trying to add new sasl mechanisms does not get applied
|
||||
until the server is restarted again. [1]
|
||||
|
||||
We were also overwriting memory when we stripped the commas from
|
||||
the allowed machanism list. THis lead to the allowed mechanisms
|
||||
to get truncated,and permanently lose certain mechs. [2]
|
||||
|
||||
A crash with PLAIN sasl mechanism was also found. [3]
|
||||
|
||||
Fix Description: To address allowed sasl mechs, we no longer explicitly the mechanisms
|
||||
during the sasl_init at server startup. Instead we check the allowed
|
||||
list ourselves during a bind. [1]
|
||||
|
||||
When setting the allowed sasl mechs, make a copy of the value to
|
||||
apply the changes to(removing coamms), and do not change the original
|
||||
value as it's still being used. [2]
|
||||
|
||||
The crash when using sasl PLAIN was due to unlocking a rwlock that
|
||||
was not locked. [3]
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49379
|
||||
|
||||
Reviewed by: tbordaz(Thanks!)
|
||||
|
||||
(cherry picked from commit c78f41db31752a99aadd6abcbf7a1d852a8e7931)
|
||||
---
|
||||
dirsrvtests/tests/suites/sasl/allowed_mechs.py | 114 ++++++++++++++++++++++--
|
||||
dirsrvtests/tests/suites/sasl/plain.py | 10 ++-
|
||||
ldap/servers/slapd/libglobs.c | 23 ++---
|
||||
ldap/servers/slapd/saslbind.c | 116 +++++++++++++------------
|
||||
4 files changed, 187 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/allowed_mechs.py b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
index 7958db4..5b1b92c 100644
|
||||
--- a/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
+++ b/dirsrvtests/tests/suites/sasl/allowed_mechs.py
|
||||
@@ -8,45 +8,141 @@
|
||||
#
|
||||
|
||||
import pytest
|
||||
-import ldap
|
||||
-
|
||||
-import time
|
||||
-
|
||||
+import os
|
||||
from lib389.topologies import topology_st
|
||||
|
||||
+
|
||||
def test_sasl_allowed_mechs(topology_st):
|
||||
+ """Test the alloweed sasl mechanism feature
|
||||
+
|
||||
+ :ID: ab7d9f86-8cfe-48c3-8baa-739e599f006a
|
||||
+ :feature: Allowed sasl mechanisms
|
||||
+ :steps: 1. Get the default list of mechanisms
|
||||
+ 2. Set allowed mechanism PLAIN, and verify it's correctly listed
|
||||
+ 3. Restart server, and verify list is still correct
|
||||
+ 4. Test EXTERNAL is properly listed
|
||||
+ 5. Add GSSAPI to the existing list, and verify it's correctly listed
|
||||
+ 6. Restart server and verify list is still correct
|
||||
+ 7. Add ANONYMOUS to the existing list, and veirfy it's correctly listed
|
||||
+ 8. Restart server and verify list is still correct
|
||||
+ 9. Remove GSSAPI and verify it's correctly listed
|
||||
+ 10. Restart server and verify list is still correct
|
||||
+ 11. Reset allowed list to nothing, verify "all" the mechanisms are returned
|
||||
+ 12. Restart server and verify list is still correct
|
||||
+
|
||||
+ :expectedresults: The supported mechanisms supported what is set for the allowed
|
||||
+ mechanisms
|
||||
+ """
|
||||
standalone = topology_st.standalone
|
||||
|
||||
# Get the supported mechs. This should contain PLAIN, GSSAPI, EXTERNAL at least
|
||||
+ standalone.log.info("Test we have some of the default mechanisms")
|
||||
orig_mechs = standalone.rootdse.supported_sasl()
|
||||
print(orig_mechs)
|
||||
assert('GSSAPI' in orig_mechs)
|
||||
assert('PLAIN' in orig_mechs)
|
||||
assert('EXTERNAL' in orig_mechs)
|
||||
|
||||
- # Now edit the supported mechs. CHeck them again.
|
||||
+ # Now edit the supported mechs. Check them again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN")
|
||||
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs) # Should always be in the allowed list, even if not set.
|
||||
+ assert('GSSAPI' not in limit_mechs) # Should not be there!
|
||||
|
||||
+ # Restart the server a few times and make sure nothing changes
|
||||
+ standalone.log.info("Restart server and make sure we still have correct allowed mechs")
|
||||
+ standalone.restart()
|
||||
+ standalone.restart()
|
||||
limit_mechs = standalone.rootdse.supported_sasl()
|
||||
assert('PLAIN' in limit_mechs)
|
||||
- # Should always be in the allowed list, even if not set.
|
||||
assert('EXTERNAL' in limit_mechs)
|
||||
- # Should not be there!
|
||||
assert('GSSAPI' not in limit_mechs)
|
||||
|
||||
+ # Set EXTERNAL, even though its always supported
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and EXTERNAL")
|
||||
standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, EXTERNAL')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+
|
||||
+ # Now edit the supported mechs. Check them again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and GSSAPI")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, GSSAPI')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Restart server twice and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ standalone.restart() # For ticket 49379 (test double restart)
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Add ANONYMOUS to the supported mechs and test again.
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN, GSSAPI, and ANONYMOUS")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, GSSAPI, ANONYMOUS')
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 4)
|
||||
+
|
||||
+ # Restart server and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ standalone.restart() # For ticket 49379 (test double restart)
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 4)
|
||||
|
||||
+ # Remove GSSAPI
|
||||
+ standalone.log.info("Edit mechanisms to allow just PLAIN and ANONYMOUS")
|
||||
+ standalone.config.set('nsslapd-allowed-sasl-mechanisms', 'PLAIN, ANONYMOUS')
|
||||
limit_mechs = standalone.rootdse.supported_sasl()
|
||||
assert('PLAIN' in limit_mechs)
|
||||
assert('EXTERNAL' in limit_mechs)
|
||||
- # Should not be there!
|
||||
assert('GSSAPI' not in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
+
|
||||
+ # Restart server and make sure the allowed list is the same
|
||||
+ standalone.restart()
|
||||
+ limit_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert('PLAIN' in limit_mechs)
|
||||
+ assert('EXTERNAL' in limit_mechs)
|
||||
+ assert('GSSAPI' not in limit_mechs)
|
||||
+ assert('ANONYMOUS' in limit_mechs)
|
||||
+ assert(len(limit_mechs) == 3)
|
||||
|
||||
# Do a config reset
|
||||
+ standalone.log.info("Reset allowed mechaisms")
|
||||
standalone.config.reset('nsslapd-allowed-sasl-mechanisms')
|
||||
|
||||
# check the supported list is the same as our first check.
|
||||
+ standalone.log.info("Check that we have the original set of mechanisms")
|
||||
final_mechs = standalone.rootdse.supported_sasl()
|
||||
- print(final_mechs)
|
||||
assert(set(final_mechs) == set(orig_mechs))
|
||||
|
||||
+ # Check it after a restart
|
||||
+ standalone.log.info("Check that we have the original set of mechanisms after a restart")
|
||||
+ standalone.restart()
|
||||
+ final_mechs = standalone.rootdse.supported_sasl()
|
||||
+ assert(set(final_mechs) == set(orig_mechs))
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ # Run isolated
|
||||
+ # -s for DEBUG mode
|
||||
+ CURRENT_FILE = os.path.realpath(__file__)
|
||||
+ pytest.main("-s %s" % CURRENT_FILE)
|
||||
diff --git a/dirsrvtests/tests/suites/sasl/plain.py b/dirsrvtests/tests/suites/sasl/plain.py
|
||||
index 91ccb02..6bf39a8 100644
|
||||
--- a/dirsrvtests/tests/suites/sasl/plain.py
|
||||
+++ b/dirsrvtests/tests/suites/sasl/plain.py
|
||||
@@ -15,9 +15,11 @@ from lib389.topologies import topology_st
|
||||
from lib389.utils import *
|
||||
from lib389.sasl import PlainSASL
|
||||
from lib389.idm.services import ServiceAccounts
|
||||
+from lib389._constants import (SECUREPORT_STANDALONE1, DEFAULT_SUFFIX)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
+
|
||||
def test_sasl_plain(topology_st):
|
||||
|
||||
standalone = topology_st.standalone
|
||||
@@ -38,7 +40,7 @@ def test_sasl_plain(topology_st):
|
||||
standalone.rsa.create()
|
||||
# Set the secure port and nsslapd-security
|
||||
# Could this fail with selinux?
|
||||
- standalone.config.set('nsslapd-secureport', '%s' % SECUREPORT_STANDALONE1 )
|
||||
+ standalone.config.set('nsslapd-secureport', '%s' % SECUREPORT_STANDALONE1)
|
||||
standalone.config.set('nsslapd-security', 'on')
|
||||
# Do we need to restart to allow starttls?
|
||||
standalone.restart()
|
||||
@@ -65,12 +67,14 @@ def test_sasl_plain(topology_st):
|
||||
# I can not solve. I think it's leaking state across connections in start_tls_s?
|
||||
|
||||
# Check that it works with TLS
|
||||
- conn = standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True, certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
+ conn = standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True,
|
||||
+ certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
conn.close()
|
||||
|
||||
# Check that it correct fails our bind if we don't have the password.
|
||||
auth_tokens = PlainSASL("dn:%s" % sa.dn, 'password-wrong')
|
||||
with pytest.raises(ldap.INVALID_CREDENTIALS):
|
||||
- standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=False, connOnly=True, certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
+ standalone.openConnection(saslmethod='PLAIN', sasltoken=auth_tokens, starttls=True, connOnly=True,
|
||||
+ certdir=standalone.get_cert_dir(), reqcert=ldap.OPT_X_TLS_NEVER)
|
||||
|
||||
# Done!
|
||||
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||
index bb51827..2fb4bab 100644
|
||||
--- a/ldap/servers/slapd/libglobs.c
|
||||
+++ b/ldap/servers/slapd/libglobs.c
|
||||
@@ -7137,22 +7137,25 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
|
||||
|
||||
/* During a reset, the value is "", so we have to handle this case. */
|
||||
if (strcmp(value, "") != 0) {
|
||||
- /* cyrus sasl doesn't like comma separated lists */
|
||||
- remove_commas(value);
|
||||
+ char *nval = slapi_ch_strdup(value);
|
||||
|
||||
- if(invalid_sasl_mech(value)){
|
||||
- slapi_log_err(SLAPI_LOG_ERR,"config_set_allowed_sasl_mechs",
|
||||
- "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
- "characters, upto 20 characters, that are upper-case letters, "
|
||||
- "digits, hyphens, or underscores\n", value);
|
||||
+ /* cyrus sasl doesn't like comma separated lists */
|
||||
+ remove_commas(nval);
|
||||
+
|
||||
+ if (invalid_sasl_mech(nval)) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, "config_set_allowed_sasl_mechs",
|
||||
+ "Invalid value/character for sasl mechanism (%s). Use ASCII "
|
||||
+ "characters, upto 20 characters, that are upper-case letters, "
|
||||
+ "digits, hyphens, or underscores\n",
|
||||
+ nval);
|
||||
+ slapi_ch_free_string(&nval);
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
-
|
||||
CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||
slapi_ch_free_string(&slapdFrontendConfig->allowed_sasl_mechs);
|
||||
slapi_ch_array_free(slapdFrontendConfig->allowed_sasl_mechs_array);
|
||||
- slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
|
||||
- slapdFrontendConfig->allowed_sasl_mechs_array = slapi_str2charray_ext(value, " ", 0);
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs = nval;
|
||||
+ slapdFrontendConfig->allowed_sasl_mechs_array = slapi_str2charray_ext(nval, " ", 0);
|
||||
CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||
} else {
|
||||
/* If this value is "", we need to set the list to *all* possible mechs */
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 134f5aa..03e2a97 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -169,8 +169,6 @@ static int ids_sasl_getopt(
|
||||
}
|
||||
} else if (strcasecmp(option, "auxprop_plugin") == 0) {
|
||||
*result = "iDS";
|
||||
- } else if (strcasecmp(option, "mech_list") == 0){
|
||||
- *result = config_get_allowed_sasl_mechs();
|
||||
}
|
||||
|
||||
if (*result) *len = strlen(*result);
|
||||
@@ -572,12 +570,8 @@ static int ids_sasl_userdb_checkpass(sasl_conn_t *conn, void *context, const cha
|
||||
slapi_pblock_set(pb, SLAPI_BIND_METHOD, &method);
|
||||
/* Feed it to pw_verify_be_dn */
|
||||
bind_result = pw_verify_be_dn(pb, &referral);
|
||||
- /* Now check the result, and unlock be if needed. */
|
||||
- if (bind_result == SLAPI_BIND_SUCCESS || bind_result == SLAPI_BIND_ANONYMOUS) {
|
||||
- Slapi_Backend *be = NULL;
|
||||
- slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
||||
- slapi_be_Unlock(be);
|
||||
- } else if (bind_result == SLAPI_BIND_REFERRAL) {
|
||||
+ /* Now check the result. */
|
||||
+ if (bind_result == SLAPI_BIND_REFERRAL) {
|
||||
/* If we have a referral do we ignore it for sasl? */
|
||||
slapi_entry_free(referral);
|
||||
}
|
||||
@@ -760,22 +754,25 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
/* If we have a connection, get the provided list from SASL */
|
||||
- if (pb->pb_conn != NULL) {
|
||||
- sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
|
||||
-
|
||||
- /* sasl library mechanisms are connection dependent */
|
||||
- PR_EnterMonitor(pb->pb_conn->c_mutex);
|
||||
- if (sasl_listmech(sasl_conn,
|
||||
- NULL, /* username */
|
||||
- "", ",", "",
|
||||
- &str, NULL, NULL) == SASL_OK) {
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
- /* merge into result set */
|
||||
- dupstr = slapi_ch_strdup(str);
|
||||
- others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
- charray_merge(&sup_ret, others, 1);
|
||||
- charray_free(others);
|
||||
- slapi_ch_free((void**)&dupstr);
|
||||
+ if (pb_conn != NULL) {
|
||||
+ sasl_conn = (sasl_conn_t*)pb_conn->c_sasl_conn;
|
||||
+ if (sasl_conn != NULL) {
|
||||
+ /* sasl library mechanisms are connection dependent */
|
||||
+ PR_EnterMonitor(pb_conn->c_mutex);
|
||||
+ if (sasl_listmech(sasl_conn,
|
||||
+ NULL, /* username */
|
||||
+ "", ",", "",
|
||||
+ &str, NULL, NULL) == SASL_OK) {
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "sasl library mechs: %s\n", str);
|
||||
+ /* merge into result set */
|
||||
+ dupstr = slapi_ch_strdup(str);
|
||||
+ others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
|
||||
+
|
||||
+ charray_merge(&sup_ret, others, 1);
|
||||
+ charray_free(others);
|
||||
+ slapi_ch_free((void**)&dupstr);
|
||||
+ }
|
||||
+ PR_ExitMonitor(pb_conn->c_mutex);
|
||||
}
|
||||
PR_ExitMonitor(pb->pb_conn->c_mutex);
|
||||
}
|
||||
@@ -785,7 +782,7 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
|
||||
/* Remove any content that isn't in the allowed list */
|
||||
if (config_ret != NULL) {
|
||||
- /* Get the set of supported mechs in the insection of the two */
|
||||
+ /* Get the set of supported mechs in the intersection of the two */
|
||||
ret = charray_intersection(sup_ret, config_ret);
|
||||
charray_free(sup_ret);
|
||||
charray_free(config_ret);
|
||||
@@ -816,41 +813,52 @@ char **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 *dupstr;
|
||||
- const char *str;
|
||||
- int sasl_result = 0;
|
||||
- sasl_conn_t *sasl_conn = (sasl_conn_t *)pb->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;
|
||||
- }
|
||||
+ 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, ",");
|
||||
+ dupstr = slapi_ch_strdup(str);
|
||||
+ mechs = slapi_str2charray(dupstr, ",");
|
||||
+ allowed_mechs = config_get_allowed_sasl_mechs_array();
|
||||
|
||||
- for (i = 0; mechs[i] != NULL; i++) {
|
||||
- if (strcasecmp(mech, mechs[i]) == 0) {
|
||||
- ret = 1;
|
||||
- break;
|
||||
+ 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;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- charray_free(mechs);
|
||||
- slapi_ch_free((void**)&dupstr);
|
||||
+ charray_free(allowed_mechs);
|
||||
+ charray_free(mechs);
|
||||
+ slapi_ch_free((void **)&dupstr);
|
||||
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n");
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n");
|
||||
|
||||
- return ret;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
From 4a51a17762fb4e7ce1beb0600916fed8b45a5483 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 18 Sep 2017 15:06:06 -0400
|
||||
Subject: [PATCH] Fix cherry-pick error from sasl mech commit
|
||||
|
||||
---
|
||||
ldap/servers/slapd/saslbind.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
||||
index 03e2a97..8e94ee6 100644
|
||||
--- a/ldap/servers/slapd/saslbind.c
|
||||
+++ b/ldap/servers/slapd/saslbind.c
|
||||
@@ -745,11 +745,14 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
|
||||
const char *str;
|
||||
char *dupstr;
|
||||
sasl_conn_t *sasl_conn;
|
||||
+ Connection *pb_conn = NULL;
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_listmech", "=>\n");
|
||||
|
||||
PR_ASSERT(pb);
|
||||
|
||||
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
||||
+
|
||||
/* hard-wired mechanisms and slapi plugin registered mechanisms */
|
||||
sup_ret = slapi_get_supported_saslmechanisms_copy();
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
From 2741a6db134ad40662cfa0233c4542d2d4148997 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 | 68 ++++----
|
||||
3 files changed, 223 insertions(+), 36 deletions(-)
|
||||
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 0000000..e69de29
|
||||
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 0000000..1aac6b8
|
||||
--- /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 66c6c7f..87d4890 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -2190,48 +2190,44 @@ bail:
|
||||
static int cos_cache_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,
|
||||
vattr_type_list_context *type_context,int flags)
|
||||
{
|
||||
- int ret = 0;
|
||||
- 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");
|
||||
-
|
||||
- if(cos_cache_getref((cos_cache **)&pCache) < 1)
|
||||
- {
|
||||
- /* problems we are hosed */
|
||||
- slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_cache_vattr_types - Failed to get class of service reference\n");
|
||||
- goto bail;
|
||||
- }
|
||||
-
|
||||
- while(index < pCache->attrCount )
|
||||
- {
|
||||
- if(slapi_utf8casecmp(
|
||||
- (unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
||||
- (unsigned char *)lastattr))
|
||||
- {
|
||||
- lastattr = pCache->ppAttrIndex[index]->pAttrName;
|
||||
+ int ret = 0;
|
||||
+ int index = 0;
|
||||
+ cosCache *pCache;
|
||||
+ char *lastattr = "thisisfakeforcos";
|
||||
|
||||
- if(1 == cos_cache_query_attr(pCache, NULL, e, lastattr, NULL, NULL,
|
||||
- NULL, &props, NULL))
|
||||
- {
|
||||
- /* entry contains this attr */
|
||||
- vattr_type_thang thang = {0};
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
|
||||
|
||||
- thang.type_name = lastattr;
|
||||
- thang.type_flags = props;
|
||||
+ if (cos_cache_getref((cos_cache **)&pCache) < 1) {
|
||||
+ /* problems we are hosed */
|
||||
+ slapi_log_err(SLAPI_LOG_PLUGIN, COS_PLUGIN_SUBSYSTEM, "cos_cache_vattr_types - Failed to get class of service reference\n");
|
||||
+ goto bail;
|
||||
+ }
|
||||
|
||||
- slapi_vattrspi_add_type(type_context,&thang,0);
|
||||
- }
|
||||
- }
|
||||
- index++;
|
||||
- }
|
||||
- cos_cache_release(pCache);
|
||||
+ while (index < pCache->attrCount) {
|
||||
+ int props = 0;
|
||||
+ if (slapi_utf8casecmp(
|
||||
+ (unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
||||
+ (unsigned char *)lastattr)) {
|
||||
+ lastattr = pCache->ppAttrIndex[index]->pAttrName;
|
||||
+
|
||||
+ if (1 == cos_cache_query_attr(pCache, NULL, e, lastattr, NULL, NULL,
|
||||
+ NULL, &props, NULL)) {
|
||||
+ /* entry contains this attr */
|
||||
+ vattr_type_thang thang = {0};
|
||||
+
|
||||
+ thang.type_name = lastattr;
|
||||
+ thang.type_flags = props;
|
||||
+
|
||||
+ slapi_vattrspi_add_type(type_context, &thang, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ index++;
|
||||
+ }
|
||||
+ cos_cache_release(pCache);
|
||||
|
||||
bail:
|
||||
|
||||
-slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_vattr_types\n");
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_vattr_types\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.5
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
From 1787e9ffda09f9ec8518ceaede5cf1ef014c5d17 Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Wed, 27 Sep 2017 10:58:36 +0200
|
||||
Subject: [PATCH] Ticket: 49180 - backport 1.3.6 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 39449b6..7f34059 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
|
||||
@@ -1502,7 +1502,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)
|
||||
{
|
||||
@@ -1525,7 +1535,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.9.5
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From 91c80c06affa3f4bfe106d2291efc360ab2b421d 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 8a824ac4a..e22bc9c39 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -1054,11 +1054,11 @@ valueset_array_to_sorted_quick (const Slapi_Attr *a, Slapi_ValueSet *vs, size_t
|
||||
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
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
From 64b9d015523b4ae379ff2d72fc73da173be8a712 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, 102 insertions(+), 69 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
||||
index e22bc9c39..ae0a13fdc 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -741,7 +741,10 @@ 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++)
|
||||
@@ -752,91 +755,122 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
|
||||
} 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 ] ....
|
||||
*
|
||||
- * 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.
|
||||
+ * 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]
|
||||
*
|
||||
- * 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.
|
||||
+ * Looping a few more times would yield:
|
||||
*
|
||||
- * 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 x x]
|
||||
+ * sorted: [_0 _1 3 0 1]
|
||||
+ *
|
||||
+ * va2: [a c d x]
|
||||
+ * sorted: [_0 _1 _2 0 1]
|
||||
+ *
|
||||
+ * 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];
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ for (j = vs->num; j < vs->max; j++) {
|
||||
vs->va[j] = NULL;
|
||||
+ if (vs->sorted) {
|
||||
+ vs->sorted[j] = -1;
|
||||
+ }
|
||||
}
|
||||
- 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;
|
||||
+ } else {
|
||||
+ slapi_valueset_done(vs);
|
||||
}
|
||||
|
||||
- /* All the values were deleted, we can discard the whole array. */
|
||||
- if(vs->num == 0) {
|
||||
- if(vs->sorted) {
|
||||
- slapi_ch_free ((void **)&vs->sorted);
|
||||
- }
|
||||
- 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 */
|
||||
+ /* 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;
|
||||
@@ -847,7 +881,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
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 43c73ca572af6a4bdc9b5994a9640f4d4e713cc2 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 ae0a13fdc..8730d9f56 100644
|
||||
--- a/ldap/servers/slapd/valueset.c
|
||||
+++ b/ldap/servers/slapd/valueset.c
|
||||
@@ -744,7 +744,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++)
|
||||
@@ -814,7 +814,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 */
|
||||
@@ -868,7 +868,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
|
||||
|
874
SOURCES/0077-Ticket-48235-Remove-memberOf-global-lock.patch
Normal file
874
SOURCES/0077-Ticket-48235-Remove-memberOf-global-lock.patch
Normal file
|
@ -0,0 +1,874 @@
|
|||
From 229f61f5f54aeb9e1a1756f731dfe7bcedbf148c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Fri, 13 Oct 2017 07:09:08 -0400
|
||||
Subject: [PATCH 06/10] 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: tbordaz & firstyear(Thanks!!)
|
||||
---
|
||||
ldap/servers/plugins/memberof/memberof.c | 312 +++---------------------
|
||||
ldap/servers/plugins/memberof/memberof.h | 17 ++
|
||||
ldap/servers/plugins/memberof/memberof_config.c | 152 +++++++++++-
|
||||
3 files changed, 200 insertions(+), 281 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
|
||||
index 9bbe13c9c..bbf47dd49 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.c
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.c
|
||||
@@ -49,13 +49,10 @@ 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;
|
||||
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,7 @@ 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;
|
||||
@@ -189,14 +175,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 ***/
|
||||
|
||||
@@ -375,12 +356,6 @@ int 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;
|
||||
@@ -388,9 +363,6 @@ int 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)
|
||||
@@ -482,18 +454,7 @@ int memberof_postop_close(Slapi_PBlock *pb)
|
||||
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;
|
||||
@@ -554,7 +515,7 @@ int 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;
|
||||
|
||||
@@ -583,9 +544,6 @@ int 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
|
||||
@@ -594,7 +552,6 @@ int 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;
|
||||
}
|
||||
|
||||
@@ -618,7 +575,6 @@ int memberof_postop_del(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
- memberof_unlock();
|
||||
bail:
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
@@ -813,7 +769,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);
|
||||
@@ -960,7 +916,7 @@ int 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;
|
||||
@@ -988,8 +944,6 @@ int 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))
|
||||
@@ -1060,7 +1014,6 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
- memberof_unlock();
|
||||
bail:
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
@@ -1220,7 +1173,7 @@ int memberof_postop_modify(Slapi_PBlock *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);
|
||||
@@ -1267,8 +1220,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
{
|
||||
int op = slapi_mod_get_operation(smod);
|
||||
|
||||
- memberof_lock();
|
||||
-
|
||||
/* the modify op decides the function */
|
||||
switch(op & ~LDAP_MOD_BVALUES)
|
||||
{
|
||||
@@ -1280,7 +1231,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"memberof_postop_modify - Failed to add dn (%s) to target. "
|
||||
"Error (%d)\n", slapi_sdn_get_dn(sdn), ret );
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
@@ -1299,7 +1249,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"memberof_postop_modify - Failed to replace list (%s). "
|
||||
"Error (%d)\n", slapi_sdn_get_dn(sdn), ret );
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@@ -1311,7 +1260,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"memberof_postop_modify: failed to remove dn (%s). "
|
||||
"Error (%d)\n", slapi_sdn_get_dn(sdn), ret );
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@@ -1326,7 +1274,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
"memberof_postop_modify - Failed to replace values in dn (%s). "
|
||||
"Error (%d)\n", slapi_sdn_get_dn(sdn), ret );
|
||||
slapi_mod_done(next_mod);
|
||||
- memberof_unlock();
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
@@ -1342,8 +1289,6 @@ int memberof_postop_modify(Slapi_PBlock *pb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
-
|
||||
- memberof_unlock();
|
||||
}
|
||||
|
||||
slapi_mod_done(next_mod);
|
||||
@@ -1398,7 +1343,7 @@ int 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 );
|
||||
|
||||
@@ -1424,8 +1369,6 @@ int 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))
|
||||
@@ -1438,8 +1381,6 @@ int memberof_postop_add(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- memberof_unlock();
|
||||
memberof_free_config(&configCopy);
|
||||
}
|
||||
}
|
||||
@@ -2201,7 +2142,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;
|
||||
@@ -2298,14 +2239,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) {
|
||||
+ 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);
|
||||
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
|
||||
@@ -2390,9 +2331,9 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn,
|
||||
memberof_get_groups_callback, &member_data, &cached, member_data.use_cache);
|
||||
|
||||
merge_ancestors(&member_ndn_val, &member_data, data);
|
||||
- if (!cached && member_data.use_cache)
|
||||
- cache_ancestors(&member_ndn_val, &member_data);
|
||||
-
|
||||
+ if (!cached && member_data.use_cache) {
|
||||
+ cache_ancestors(config, &member_ndn_val, &member_data);
|
||||
+ }
|
||||
|
||||
slapi_value_free(&member_ndn_val);
|
||||
slapi_valueset_free(groupvals);
|
||||
@@ -2969,46 +2910,9 @@ int 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;
|
||||
@@ -3068,14 +2972,8 @@ void memberof_fixup_task_thread(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
- /* get the memberOf operation lock */
|
||||
- memberof_lock();
|
||||
-
|
||||
/* do real work */
|
||||
rc = memberof_fix_memberof(&configCopy, task, td);
|
||||
-
|
||||
- /* release the memberOf operation lock */
|
||||
- memberof_unlock();
|
||||
|
||||
done:
|
||||
if (usetxn && fixup_pb) {
|
||||
@@ -3240,7 +3138,7 @@ int memberof_fix_memberof(MemberOfConfig *config, Slapi_Task *task, task_data *t
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -3258,7 +3156,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) {
|
||||
@@ -3274,7 +3172,7 @@ ancestors_cache_lookup(const char *ndn)
|
||||
|
||||
}
|
||||
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)
|
||||
@@ -3292,7 +3190,7 @@ 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) {
|
||||
@@ -3305,7 +3203,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)
|
||||
@@ -3322,7 +3220,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) {
|
||||
@@ -3360,10 +3258,11 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
- /* Check if the entry has not already been fixed */
|
||||
+ /* 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)) {
|
||||
- slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: Entry %s already fixed up\n", 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;
|
||||
}
|
||||
|
||||
@@ -3383,9 +3282,9 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
#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);
|
||||
@@ -3400,6 +3299,7 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
/* If we found some groups, replace the existing memberOf attribute
|
||||
* with the found values. */
|
||||
if (groups && slapi_valueset_count(groups))
|
||||
@@ -3439,9 +3339,9 @@ int 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",
|
||||
dn_copy, PR_GetError());
|
||||
@@ -3539,150 +3439,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, void *arg)
|
||||
-{
|
||||
- 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, void *arg)
|
||||
+int
|
||||
+memberof_use_txn()
|
||||
{
|
||||
- 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;
|
||||
+ return usetxn;
|
||||
}
|
||||
-
|
||||
-static void ancestor_hashtable_empty(char *msg)
|
||||
-{
|
||||
-#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
|
||||
- }
|
||||
-
|
||||
-}
|
||||
-
|
||||
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
|
||||
index 9a3a6a25d..a01c4d247 100644
|
||||
--- a/ldap/servers/plugins/memberof/memberof.h
|
||||
+++ b/ldap/servers/plugins/memberof/memberof.h
|
||||
@@ -62,8 +62,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
|
||||
@@ -88,5 +102,8 @@ int memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Ent
|
||||
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 c3474bf2c..3cc7c4d9c 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.
|
||||
@@ -33,7 +33,9 @@
|
||||
|
||||
/*
|
||||
* function prototypes
|
||||
- */
|
||||
+ */
|
||||
+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, Slapi_Entry* entryBefore, Slapi_Entry* e,
|
||||
@@ -48,7 +50,7 @@ static int memberof_search (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_En
|
||||
/* 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;
|
||||
|
||||
@@ -696,6 +698,12 @@ 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)
|
||||
{
|
||||
@@ -799,6 +807,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);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1001,3 +1017,131 @@ 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
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From bc190eeaaffbb514f69664b4d033dc593a78683b 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)
|
||||
(cherry picked from commit 2ef4e813b8f6b92908ff553a704808cbbd425b5d)
|
||||
---
|
||||
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 7161bace1..f60df194b 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/import.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/import.c
|
||||
@@ -234,7 +234,7 @@ static void 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
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
From 8031684255007b42df3d08b80e674aefb0ebfb2d 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 | 101 +++++++++++----------
|
||||
1 file changed, 51 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 053103bd0..814f1cac0 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -1911,12 +1911,13 @@ 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 "
|
||||
- "cleanallruv extended op, retrying in %d seconds",interval);
|
||||
- if(!slapi_is_shutting_down()){
|
||||
- PR_Lock( notify_lock );
|
||||
- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
||||
- PR_Unlock( notify_lock );
|
||||
+ 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()) {
|
||||
+ PR_Lock(notify_lock);
|
||||
+ PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
|
||||
+ PR_Unlock(notify_lock);
|
||||
}
|
||||
if(interval < 14400){ /* 4 hour max */
|
||||
interval = interval * 2;
|
||||
@@ -1952,8 +1953,8 @@ 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)",
|
||||
- agmt_get_long_name(agmt));
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica is not cleaned yet (%s)",
|
||||
+ agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
|
||||
@@ -1969,12 +1970,13 @@ 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, "
|
||||
- "retrying in %d seconds", interval);
|
||||
- PR_Lock( notify_lock );
|
||||
- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
||||
- PR_Unlock( notify_lock );
|
||||
+ if (!slapi_is_shutting_down()) {
|
||||
+ 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);
|
||||
+ PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
|
||||
+ PR_Unlock(notify_lock);
|
||||
}
|
||||
|
||||
if(interval < 14400){ /* 4 hour max */
|
||||
@@ -2008,11 +2010,11 @@ done:
|
||||
/*
|
||||
* Shutdown or abort
|
||||
*/
|
||||
- if(!is_task_aborted(data->rid) || slapi_is_shutting_down()){
|
||||
- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE,
|
||||
- "Server shutting down. Process will resume at server startup");
|
||||
+ if (!is_task_aborted(data->rid) || slapi_is_shutting_down()) {
|
||||
+ 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);
|
||||
}
|
||||
@@ -2180,7 +2182,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()){
|
||||
@@ -2289,12 +2291,12 @@ 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,
|
||||
- "Not all replicas finished aborting, retrying in %d seconds",interval);
|
||||
- if(!slapi_is_shutting_down()){
|
||||
- PR_Lock( notify_lock );
|
||||
- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
||||
- PR_Unlock( notify_lock );
|
||||
+ 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);
|
||||
+ PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
|
||||
+ PR_Unlock(notify_lock);
|
||||
}
|
||||
if(interval < 14400){ /* 4 hour max */
|
||||
interval = interval * 2;
|
||||
@@ -2336,8 +2338,8 @@ 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,
|
||||
- "Replica not caught up (%s)",agmt_get_long_name(agmt));
|
||||
+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
|
||||
+ "Replica not caught up (%s)", agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
|
||||
@@ -2346,12 +2348,12 @@ 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,
|
||||
- "Not all replicas caught up, retrying in %d seconds",interval);
|
||||
- if(!slapi_is_shutting_down()){
|
||||
- PR_Lock( notify_lock );
|
||||
- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
||||
- PR_Unlock( notify_lock );
|
||||
+ 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);
|
||||
+ PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
|
||||
+ PR_Unlock(notify_lock);
|
||||
}
|
||||
if(interval < 14400){ /* 4 hour max */
|
||||
interval = interval * 2;
|
||||
@@ -2396,8 +2398,8 @@ 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)",
|
||||
- agmt_get_long_name(agmt));
|
||||
+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica not online (%s)",
|
||||
+ agmt_get_long_name(agmt));
|
||||
break;
|
||||
}
|
||||
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
|
||||
@@ -2406,8 +2408,8 @@ 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...",
|
||||
- interval);
|
||||
+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas online, retrying in %d seconds...",
|
||||
+ interval);
|
||||
|
||||
if(!slapi_is_shutting_down()){
|
||||
PR_Lock( notify_lock );
|
||||
@@ -3174,11 +3176,11 @@ 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);
|
||||
- PR_Lock( notify_lock );
|
||||
- PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
||||
- PR_Unlock( notify_lock );
|
||||
+ if (!slapi_is_shutting_down()) {
|
||||
+ 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);
|
||||
}
|
||||
|
||||
if(interval < 14400){ /* 4 hour max */
|
||||
@@ -3296,9 +3298,10 @@ 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,
|
||||
- "Replica %s does not support the CLEANALLRUV task. "
|
||||
- "Sending replica CLEANRUV task...", slapi_sdn_get_dn(agmt_get_dn_byref(ra)));
|
||||
+ 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)));
|
||||
/*
|
||||
* Ok, this replica doesn't know about CLEANALLRUV, so just manually
|
||||
* add the CLEANRUV task to the replica.
|
||||
@@ -3463,9 +3466,9 @@ 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,
|
||||
- "Replica maxcsn (%s) is not caught up with deleted replica's maxcsn(%s)",
|
||||
- remote_maxcsn, maxcsn);
|
||||
+ 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;
|
||||
} else {
|
||||
/* ok this replica is caught up */
|
||||
@@ -3636,7 +3639,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;
|
||||
@@ -3661,7 +3663,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
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,96 @@
|
|||
From df5000efced2d00aa0fc6546fcf6fc7b02e27256 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Mon, 6 Nov 2017 22:30:55 -0500
|
||||
Subject: [PATCH] Ticket 49441 - Import crashes with large indexed binary
|
||||
attributes
|
||||
|
||||
Bug Description: Importing an ldif file that contains entries with large
|
||||
binary attributes that are indexed crashes the server.
|
||||
The crash occurs when "encoding" the binary value to a
|
||||
string for debug logging, where we "underflow" the buffer
|
||||
space index which then allows the string buffer to overflow.
|
||||
|
||||
Fix Description: While filling the string buffer with the encoded binary
|
||||
value we need to make sure if the buffer space is greater
|
||||
than zero before decrementing it.
|
||||
|
||||
Also check if trace logging is being used before we actually
|
||||
call the logging function which calls the "encoded" function
|
||||
first. This way we avoid this costly "encoding" on every
|
||||
index call we make.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49441
|
||||
|
||||
Reviewed by: firstyear(Thanks!)
|
||||
---
|
||||
ldap/servers/slapd/back-ldbm/index.c | 21 ++++++++++-----------
|
||||
1 file changed, 10 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
|
||||
index d4de28ca3..d62052a22 100644
|
||||
--- a/ldap/servers/slapd/back-ldbm/index.c
|
||||
+++ b/ldap/servers/slapd/back-ldbm/index.c
|
||||
@@ -808,7 +808,10 @@ encode (const struct berval* data, char buf[BUFSIZ])
|
||||
bufSpace -= (s - first);
|
||||
}
|
||||
do {
|
||||
- *bufNext++ = '\\'; --bufSpace;
|
||||
+ if (bufSpace) {
|
||||
+ *bufNext++ = '\\';
|
||||
+ --bufSpace;
|
||||
+ }
|
||||
if (bufSpace < 2) {
|
||||
memcpy (bufNext, "..", 2);
|
||||
bufNext += 2;
|
||||
@@ -903,8 +906,10 @@ index_read_ext_allids(
|
||||
slapi_log_err(SLAPI_LOG_ERR, "index_read_ext_allids", "NULL prefix\n");
|
||||
return NULL;
|
||||
}
|
||||
- slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "=> ( \"%s\" %s \"%s\" )\n",
|
||||
- type, prefix, encode (val, buf));
|
||||
+ if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) {
|
||||
+ slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "=> ( \"%s\" %s \"%s\" )\n",
|
||||
+ type, prefix, encode (val, buf));
|
||||
+ }
|
||||
|
||||
basetype = typebuf;
|
||||
if ( (basetmp = slapi_attr_basetype( type, typebuf, sizeof(typebuf) ))
|
||||
@@ -1737,16 +1742,13 @@ addordel_values(
|
||||
*/
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
key.ulen = tmpbuflen;
|
||||
-#ifdef LDAP_ERROR_LOGGING
|
||||
- /* XXX if ( slapd_ldap_debug & LDAP_DEBUG_TRACE ) XXX */
|
||||
- {
|
||||
+ if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) {
|
||||
char encbuf[BUFSIZ];
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "addordel_values", "%s_value(\"%s\")\n",
|
||||
(flags & BE_INDEX_ADD) ? "add" : "del",
|
||||
encoded (&key, encbuf));
|
||||
}
|
||||
-#endif
|
||||
|
||||
if (NULL != txn) {
|
||||
db_txn = txn->back_txn_txn;
|
||||
@@ -1907,16 +1909,13 @@ addordel_values_sv(
|
||||
*/
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
key.ulen = tmpbuflen;
|
||||
-#ifdef LDAP_ERROR_LOGGING
|
||||
- /* XXX if ( slapd_ldap_debug & LDAP_DEBUG_TRACE ) XXX */
|
||||
- {
|
||||
+ if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) {
|
||||
char encbuf[BUFSIZ];
|
||||
|
||||
slapi_log_err(SLAPI_LOG_TRACE, "addordel_values_sv", "%s_value(\"%s\")\n",
|
||||
(flags & BE_INDEX_ADD) ? "add" : "del",
|
||||
encoded (&key, encbuf));
|
||||
}
|
||||
-#endif
|
||||
|
||||
if (NULL != txn) {
|
||||
db_txn = txn->back_txn_txn;
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
From 557f4d4ed5e37f09691d383dd8189b642ade8f2b Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Sun, 29 Oct 2017 16:32:11 +0100
|
||||
Subject: [PATCH] Ticket 49431 - replicated MODRDN fails breaking replication
|
||||
|
||||
Bug: in urp modrdn_operation not a full dn was passed to generate the conflict rdn passed
|
||||
and so the sufix test failed
|
||||
|
||||
Fix: provide full dn of new entry
|
||||
|
||||
Reviewed by: Mark, Thanks
|
||||
---
|
||||
ldap/servers/plugins/replication/urp.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c
|
||||
index 64810e9d4..21319d9f7 100644
|
||||
--- a/ldap/servers/plugins/replication/urp.c
|
||||
+++ b/ldap/servers/plugins/replication/urp.c
|
||||
@@ -433,7 +433,14 @@ urp_modrdn_operation( Slapi_PBlock *pb )
|
||||
/* The target entry is a loser */
|
||||
|
||||
char *newrdn_with_uniqueid;
|
||||
- newrdn_with_uniqueid= get_rdn_plus_uniqueid (sessionid, newrdn, op_uniqueid);
|
||||
+ char *newdn = NULL;
|
||||
+ if (new_parent_entry) {
|
||||
+ newdn = slapi_ch_smprintf("%s,%s", newrdn, slapi_entry_get_dn(new_parent_entry));
|
||||
+ } else {
|
||||
+ newdn = slapi_ch_smprintf("%s,%s", newrdn, slapi_entry_get_dn(parent_entry));
|
||||
+ }
|
||||
+ newrdn_with_uniqueid= get_rdn_plus_uniqueid (sessionid, newdn, op_uniqueid);
|
||||
+ slapi_ch_free_string(&newdn);
|
||||
if(newrdn_with_uniqueid==NULL)
|
||||
{
|
||||
op_result= LDAP_OPERATIONS_ERROR;
|
||||
--
|
||||
2.13.6
|
||||
|
4
SOURCES/389-ds-base-devel.README
Normal file
4
SOURCES/389-ds-base-devel.README
Normal file
|
@ -0,0 +1,4 @@
|
|||
For detailed information on developing plugins for
|
||||
389 Directory Server visit.
|
||||
|
||||
http://port389/wiki/Plugins
|
16
SOURCES/389-ds-base-git.sh
Normal file
16
SOURCES/389-ds-base-git.sh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
DATE=`date +%Y%m%d`
|
||||
# use a real tag name here
|
||||
VERSION=1.3.1.6
|
||||
PKGNAME=389-ds-base
|
||||
TAG=${TAG:-$PKGNAME-$VERSION}
|
||||
URL="http://git.fedorahosted.org/git/?p=389/ds.git;a=snapshot;h=$TAG;sf=tgz"
|
||||
SRCNAME=$PKGNAME-$VERSION
|
||||
|
||||
wget -O $SRCNAME.tar.gz "$URL"
|
||||
|
||||
echo convert tgz format to tar.bz2 format
|
||||
|
||||
gunzip $PKGNAME-$VERSION.tar.gz
|
||||
bzip2 $PKGNAME-$VERSION.tar
|
2859
SPECS/389-ds-base.spec
Normal file
2859
SPECS/389-ds-base.spec
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue