diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata index 6d7d3f7..3a558a8 100644 --- a/.389-ds-base.metadata +++ b/.389-ds-base.metadata @@ -1 +1 @@ -77dee99c82e77c3c3c8579b443ebb68e63d51702 SOURCES/389-ds-base-1.3.7.5.tar.bz2 +debdbca81fda1651bf73e504ca8bc8c1b48a3b59 SOURCES/389-ds-base-1.3.6.1.tar.bz2 diff --git a/.gitignore b/.gitignore index 18dc925..a990b51 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/389-ds-base-1.3.7.5.tar.bz2 +SOURCES/389-ds-base-1.3.6.1.tar.bz2 diff --git a/SOURCES/0000-Ticket-49164-Change-NS-to-acq-rel-semantics-for-atom.patch b/SOURCES/0000-Ticket-49164-Change-NS-to-acq-rel-semantics-for-atom.patch new file mode 100644 index 0000000..a779d35 --- /dev/null +++ b/SOURCES/0000-Ticket-49164-Change-NS-to-acq-rel-semantics-for-atom.patch @@ -0,0 +1,67 @@ +From 70230bf894d9c0150dca8dc6fccc2712187f7b86 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0000-Ticket-49305-Need-to-wrap-atomic-calls.patch b/SOURCES/0000-Ticket-49305-Need-to-wrap-atomic-calls.patch deleted file mode 100644 index 2710342..0000000 --- a/SOURCES/0000-Ticket-49305-Need-to-wrap-atomic-calls.patch +++ /dev/null @@ -1,1514 +0,0 @@ -From f19dec383e24e2aaa40a6bdce2ca0e657ffc6e10 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 27 Sep 2017 09:26:14 -0400 -Subject: [PATCH] Ticket 49305 - Need to wrap atomic calls - -Bug Description: Some RHEL 7.5 platforms (ppc 32bit) still do not support - all the gcc builtin atomics. This breaks the downstream - builds. - -Fix Description: Use wrapper functions for the atomic's using #define's - to detect if builtin atomics are supported, otherwise - use the egneric nspr atomic functions. - -https://pagure.io/389-ds-base/issue/49305 - -Reviewed by: tbordaz(Thanks!) - -(cherry picked from commit af723fd632d355642babeed1dbdb5a308c21fa79) ---- - ldap/servers/slapd/attrsyntax.c | 8 +- - ldap/servers/slapd/back-ldbm/dblayer.c | 66 +++++----- - ldap/servers/slapd/entry.c | 11 +- - ldap/servers/slapd/libglobs.c | 161 ++++++++++++----------- - ldap/servers/slapd/log.c | 9 +- - ldap/servers/slapd/mapping_tree.c | 28 ++-- - ldap/servers/slapd/object.c | 8 +- - ldap/servers/slapd/psearch.c | 7 +- - ldap/servers/slapd/slapi-plugin.h | 52 ++++++++ - ldap/servers/slapd/slapi_counter.c | 100 ++++++++++++++ - ldap/servers/slapd/thread_data.c | 2 +- - src/nunc-stans/ns/ns_thrpool.c | 17 ++- - src/nunc-stans/test/test_nuncstans_stress_core.c | 42 +++++- - 13 files changed, 361 insertions(+), 150 deletions(-) - -diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c -index 03f05d9..a0a60c4 100644 ---- a/ldap/servers/slapd/attrsyntax.c -+++ b/ldap/servers/slapd/attrsyntax.c -@@ -274,7 +274,7 @@ attr_syntax_get_by_oid_locking_optional(const char *oid, PRBool use_lock, PRUint - } - asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, oid); - if (asi) { -- __atomic_add_fetch_8(&(asi->asi_refcnt), 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&(asi->asi_refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); - } - if (use_lock) { - AS_UNLOCK_READ(oid2asi_lock); -@@ -371,7 +371,7 @@ attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock, PRUi - } - asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, name); - if (NULL != asi) { -- __atomic_add_fetch_8(&(asi->asi_refcnt), 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&(asi->asi_refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); - } - if (use_lock) { - AS_UNLOCK_READ(name2asi_lock); -@@ -406,7 +406,7 @@ attr_syntax_return_locking_optional(struct asyntaxinfo *asi, PRBool use_lock) - } - if (NULL != asi) { - PRBool delete_it = PR_FALSE; -- if (0 == __atomic_sub_fetch_8(&(asi->asi_refcnt), 1, __ATOMIC_ACQ_REL)) { -+ if (0 == slapi_atomic_decr(&(asi->asi_refcnt), __ATOMIC_ACQ_REL, ATOMIC_LONG)) { - delete_it = asi->asi_marked_for_delete; - } - -@@ -540,7 +540,7 @@ attr_syntax_delete_no_lock(struct asyntaxinfo *asi, - PL_HashTableRemove(ht, asi->asi_aliases[i]); - } - } -- if (__atomic_load_8(&(asi->asi_refcnt), __ATOMIC_ACQUIRE) > 0) { -+ if (slapi_atomic_load(&(asi->asi_refcnt), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { - asi->asi_marked_for_delete = PR_TRUE; - } else { - /* This is ok, but the correct thing is to call delete first, -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index d43258d..c4c4959 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -2860,16 +2860,16 @@ int - dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flags) - { - /* -- * We either already have a DB* handle in the attrinfo structure. -- * in which case we simply return it to the caller, OR: -- * we need to make one. We do this as follows: -- * 1a) acquire the mutex that protects the handle list. -- * 1b) check that the DB* is still null. -- * 2) get the filename, and call libdb to open it -- * 3) if successful, store the result in the attrinfo stucture -- * 4) store the DB* in our own list so we can close it later. -- * 5) release the mutex. -- */ -+ * We either already have a DB* handle in the attrinfo structure. -+ * in which case we simply return it to the caller, OR: -+ * we need to make one. We do this as follows: -+ * 1a) acquire the mutex that protects the handle list. -+ * 1b) check that the DB* is still null. -+ * 2) get the filename, and call libdb to open it -+ * 3) if successful, store the result in the attrinfo stucture -+ * 4) store the DB* in our own list so we can close it later. -+ * 5) release the mutex. -+ */ - ldbm_instance *inst = (ldbm_instance *)be->be_instance_info; - int return_value = -1; - DB *pDB = NULL; -@@ -2878,9 +2878,9 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - *ppDB = NULL; - - /* it's like a semaphore -- when count > 0, any file handle that's in -- * the attrinfo will remain valid from here on. -- */ -- __atomic_add_fetch_8(&(a->ai_dblayer_count), 1, __ATOMIC_RELEASE); -+ * the attrinfo will remain valid from here on. -+ */ -+ slapi_atomic_incr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); - - if (a->ai_dblayer && ((dblayer_handle *)(a->ai_dblayer))->dblayer_dbp) { - /* This means that the pointer is valid, so we should return it. */ -@@ -2888,9 +2888,7 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - return 0; - } - -- /* attrinfo handle is NULL, at least for now -- grab the mutex and try -- * again. -- */ -+ /* attrinfo handle is NULL, at least for now -- grab the mutex and try again. */ - PR_Lock(inst->inst_handle_list_mutex); - if (a->ai_dblayer && ((dblayer_handle *)(a->ai_dblayer))->dblayer_dbp) { - /* another thread set the handle while we were waiting on the lock */ -@@ -2900,8 +2898,8 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - } - - /* attrinfo handle is still blank, and we have the mutex: open the -- * index file and stuff it in the attrinfo. -- */ -+ * index file and stuff it in the attrinfo. -+ */ - return_value = dblayer_open_file(be, attribute_name, open_flags, - a, &pDB); - if (0 == return_value) { -@@ -2911,40 +2909,36 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - - PR_ASSERT(NULL != pDB); - /* Store the returned DB* in our own private list of -- * open files */ -+ * open files */ - if (NULL == prev_handle) { - /* List was empty */ - inst->inst_handle_tail = handle; - inst->inst_handle_head = handle; - } else { -- /* Chain the handle onto the last structure in the -- * list */ -+ /* Chain the handle onto the last structure in the list */ - inst->inst_handle_tail = handle; - prev_handle->dblayer_handle_next = handle; - } -- /* Stash a pointer to our wrapper structure in the -- * attrinfo structure */ -+ /* Stash a pointer to our wrapper structure in the attrinfo structure */ - handle->dblayer_dbp = pDB; - /* And, most importantly, return something to the caller!*/ - *ppDB = pDB; -- /* and save the hande in the attrinfo structure for -- * next time */ -+ /* and save the hande in the attrinfo structure for next time */ - a->ai_dblayer = handle; - /* don't need to update count -- we incr'd it already */ - handle->dblayer_handle_ai_backpointer = &(a->ai_dblayer); - } else { - /* Did not open it OK ! */ - /* Do nothing, because return value and fact that we didn't -- * store a DB* in the attrinfo is enough -- */ -+ * store a DB* in the attrinfo is enough */ - } - PR_Unlock(inst->inst_handle_list_mutex); - - if (return_value != 0) { - /* some sort of error -- we didn't open a handle at all. -- * decrement the refcount back to where it was. -- */ -- __atomic_sub_fetch_8(&(a->ai_dblayer_count), 1, __ATOMIC_RELEASE); -+ * decrement the refcount back to where it was. -+ */ -+ slapi_atomic_decr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); - } - - return return_value; -@@ -2956,7 +2950,7 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - int - dblayer_release_index_file(backend *be __attribute__((unused)), struct attrinfo *a, DB *pDB __attribute__((unused))) - { -- __atomic_sub_fetch_8(&(a->ai_dblayer_count), 1, __ATOMIC_RELEASE); -+ slapi_atomic_decr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); - return 0; - } - -@@ -3063,13 +3057,13 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in - - dblayer_release_index_file(be, a, db); - -- while (__atomic_load_8(&(a->ai_dblayer_count), __ATOMIC_ACQUIRE) > 0) { -+ while (slapi_atomic_load(&(a->ai_dblayer_count), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { - /* someone is using this index file */ - /* ASSUMPTION: you have already set the INDEX_OFFLINE flag, because -- * you intend to mess with this index. therefore no new requests -- * for this indexfile should happen, so the dblayer_count should -- * NEVER increase. -- */ -+ * you intend to mess with this index. therefore no new requests -+ * for this indexfile should happen, so the dblayer_count should -+ * NEVER increase. -+ */ - PR_ASSERT(a->ai_indexmask & INDEX_OFFLINE); - PR_Unlock(inst->inst_handle_list_mutex); - DS_Sleep(DBLAYER_CACHE_DELAY); -diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c -index 62d10c2..289a149 100644 ---- a/ldap/servers/slapd/entry.c -+++ b/ldap/servers/slapd/entry.c -@@ -2244,18 +2244,19 @@ slapi_entry_attr_find(const Slapi_Entry *e, const char *type, Slapi_Attr **a) - - /* the following functions control virtual attribute cache invalidation */ - --static uint32_t g_virtual_watermark = 0; /* good enough to init */ -+static int32_t g_virtual_watermark = 0; /* good enough to init */ - - int - slapi_entry_vattrcache_watermark_isvalid(const Slapi_Entry *e) - { -- return e->e_virtual_watermark == __atomic_load_4(&g_virtual_watermark, __ATOMIC_ACQUIRE); -+ return e->e_virtual_watermark == slapi_atomic_load(&g_virtual_watermark, __ATOMIC_ACQUIRE, ATOMIC_INT); -+ - } - - void - slapi_entry_vattrcache_watermark_set(Slapi_Entry *e) - { -- e->e_virtual_watermark = __atomic_load_4(&g_virtual_watermark, __ATOMIC_ACQUIRE); -+ e->e_virtual_watermark = slapi_atomic_load(&g_virtual_watermark, __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - void -@@ -2268,8 +2269,8 @@ void - slapi_entrycache_vattrcache_watermark_invalidate() - { - /* Make sure the value is never 0 */ -- if (__atomic_add_fetch_4(&g_virtual_watermark, 1, __ATOMIC_RELEASE) == 0) { -- __atomic_add_fetch_4(&g_virtual_watermark, 1, __ATOMIC_RELEASE); -+ if (slapi_atomic_incr(&g_virtual_watermark, __ATOMIC_RELEASE, ATOMIC_INT) == 0) { -+ slapi_atomic_incr(&g_virtual_watermark, __ATOMIC_RELEASE, ATOMIC_INT); - } - } - -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index 0eeb16a..4c54cf7 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -1335,19 +1335,19 @@ static uint64_t active_threads = 0; - void - g_incr_active_threadcnt(void) - { -- __atomic_add_fetch_8(&active_threads, 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); - } - - void - g_decr_active_threadcnt(void) - { -- __atomic_sub_fetch_8(&active_threads, 1, __ATOMIC_RELEASE); -+ slapi_atomic_decr(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); - } - - uint64_t - g_get_active_threadcnt(void) - { -- return __atomic_load_8(&active_threads, __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); - } - - /* -@@ -1936,7 +1936,7 @@ config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, - size = NDN_DEFAULT_SIZE; - } - if (apply) { -- __atomic_store_8(&(slapdFrontendConfig->ndn_cache_max_size), size, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->ndn_cache_max_size), &size, __ATOMIC_RELEASE, ATOMIC_LONG); - } - - return retVal; -@@ -3476,7 +3476,8 @@ int32_t - config_get_dynamic_plugins(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->dynamic_plugins), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->dynamic_plugins), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ - } - - int32_t -@@ -3498,7 +3499,7 @@ int32_t - config_get_cn_uses_dn_syntax_in_dns() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->cn_uses_dn_syntax_in_dns), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->cn_uses_dn_syntax_in_dns), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t -@@ -3543,7 +3544,7 @@ config_set_onoff(const char *attrname, char *value, int32_t *configvalue, char * - newval = LDAP_OFF; - } - -- __atomic_store_4(configvalue, newval, __ATOMIC_RELEASE); -+ slapi_atomic_store(configvalue, &newval, __ATOMIC_RELEASE, ATOMIC_INT); - - return retVal; - } -@@ -3915,7 +3916,7 @@ config_set_threadnumber(const char *attrname, char *value, char *errorbuf, int a - retVal = LDAP_OPERATIONS_ERROR; - } - if (apply) { -- __atomic_store_4(&(slapdFrontendConfig->threadnumber), threadnum, __ATOMIC_RELAXED); -+ slapi_atomic_store(&(slapdFrontendConfig->threadnumber), &threadnum, __ATOMIC_RELAXED, ATOMIC_INT); - } - return retVal; - } -@@ -3944,7 +3945,7 @@ config_set_maxthreadsperconn(const char *attrname, char *value, char *errorbuf, - } - - if (apply) { -- __atomic_store_4(&(slapdFrontendConfig->maxthreadsperconn), maxthreadnum, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->maxthreadsperconn), &maxthreadnum, __ATOMIC_RELEASE, ATOMIC_INT); - } - return retVal; - } -@@ -4102,7 +4103,7 @@ config_set_ioblocktimeout(const char *attrname, char *value, char *errorbuf, int - } - - if (apply) { -- __atomic_store_4(&(slapdFrontendConfig->ioblocktimeout), nValue, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->ioblocktimeout), &nValue, __ATOMIC_RELEASE, ATOMIC_INT); - } - return retVal; - } -@@ -4606,21 +4607,22 @@ int32_t - config_get_sasl_mapping_fallback() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->sasl_mapping_fallback), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->sasl_mapping_fallback), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ - } - - int32_t - config_get_disk_monitoring() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->disk_monitoring), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->disk_monitoring), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_disk_logging_critical() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->disk_logging_critical), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->disk_logging_critical), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int -@@ -4667,14 +4669,14 @@ int32_t - config_get_ldapi_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ldapi_switch), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ldapi_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_ldapi_bind_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ldapi_bind_switch), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ldapi_bind_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - char * -@@ -4693,7 +4695,7 @@ int - config_get_ldapi_map_entries() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ldapi_map_entries), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ldapi_map_entries), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - char * -@@ -4763,7 +4765,8 @@ int32_t - config_get_slapi_counters() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->slapi_counters), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->slapi_counters), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ - } - - char * -@@ -4945,7 +4948,7 @@ int32_t - config_get_pw_change(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_change), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_change), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - -@@ -4953,7 +4956,7 @@ int32_t - config_get_pw_history(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_history), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_history), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - -@@ -4961,21 +4964,21 @@ int32_t - config_get_pw_must_change(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_must_change), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_must_change), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_allow_hashed_pw(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->allow_hashed_pw), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->allow_hashed_pw), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_pw_syntax(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_syntax), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_syntax), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - -@@ -5164,21 +5167,21 @@ int32_t - config_get_pw_is_global_policy(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_is_global_policy), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_is_global_policy), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_pw_is_legacy_policy(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_is_legacy), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_is_legacy), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_pw_exp(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_exp), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_exp), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - -@@ -5186,14 +5189,14 @@ int32_t - config_get_pw_unlock(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_unlock), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_unlock), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_pw_lockout() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->pw_policy.pw_lockout), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_lockout), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int -@@ -5213,112 +5216,112 @@ int32_t - config_get_lastmod() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->lastmod), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->lastmod), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_enquote_sup_oc() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->enquote_sup_oc), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->enquote_sup_oc), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_nagle(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->nagle), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->nagle), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_accesscontrol(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->accesscontrol), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->accesscontrol), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_return_exact_case(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->return_exact_case), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->return_exact_case), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_result_tweak(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->result_tweak), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->result_tweak), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_moddn_aci(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->moddn_aci), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->moddn_aci), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_security(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->security), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->security), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - slapi_config_get_readonly(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->readonly), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->readonly), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_schemacheck(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->schemacheck), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->schemacheck), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_schemamod(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->schemamod), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->schemamod), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_syntaxcheck(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->syntaxcheck), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->syntaxcheck), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_syntaxlogging(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->syntaxlogging), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->syntaxlogging), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_dn_validate_strict(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->dn_validate_strict), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->dn_validate_strict), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_ds4_compatible_schema(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ds4_compatible_schema), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ds4_compatible_schema), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_schema_ignore_trailing_spaces(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->schema_ignore_trailing_spaces), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->schema_ignore_trailing_spaces), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - char * -@@ -5402,7 +5405,7 @@ config_get_threadnumber(void) - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); - int32_t retVal; - -- retVal = __atomic_load_4(&(slapdFrontendConfig->threadnumber), __ATOMIC_RELAXED); -+ retVal = slapi_atomic_load(&(slapdFrontendConfig->threadnumber), __ATOMIC_RELAXED, ATOMIC_INT); - - if (retVal <= 0) { - retVal = util_get_hardware_threads(); -@@ -5420,7 +5423,7 @@ int32_t - config_get_maxthreadsperconn() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->maxthreadsperconn), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->maxthreadsperconn), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int -@@ -5452,7 +5455,7 @@ int32_t - config_get_ioblocktimeout() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ioblocktimeout), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ioblocktimeout), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int -@@ -5769,21 +5772,21 @@ int32_t - config_get_unauth_binds_switch(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->allow_unauth_binds), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->allow_unauth_binds), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_require_secure_binds(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->require_secure_binds), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->require_secure_binds), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_anon_access_switch(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->allow_anon_access), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->allow_anon_access), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int -@@ -6025,7 +6028,8 @@ int32_t - config_get_minssf_exclude_rootdse() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->minssf_exclude_rootdse), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->minssf_exclude_rootdse), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ - } - - int -@@ -6034,18 +6038,17 @@ config_set_max_filter_nest_level(const char *attrname, char *value, char *errorb - int retVal = LDAP_SUCCESS; - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); - char *endp; -- long level; -+ int32_t level; - - if (config_value_is_null(attrname, value, errorbuf, 0)) { - return LDAP_OPERATIONS_ERROR; - } - - errno = 0; -- level = strtol(value, &endp, 10); -+ level = (int32_t)strtol(value, &endp, 10); - if (*endp != '\0' || errno == ERANGE) { -- slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "(%s) value (%s) " -- "is invalid\n", -- attrname, value); -+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, -+ "(%s) value (%s) is invalid\n", attrname, value); - retVal = LDAP_OPERATIONS_ERROR; - return retVal; - } -@@ -6054,7 +6057,7 @@ config_set_max_filter_nest_level(const char *attrname, char *value, char *errorb - return retVal; - } - -- __atomic_store_4(&(slapdFrontendConfig->max_filter_nest_level), level, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->max_filter_nest_level), &level, __ATOMIC_RELEASE, ATOMIC_INT); - return retVal; - } - -@@ -6062,29 +6065,28 @@ int32_t - config_get_max_filter_nest_level() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->max_filter_nest_level), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->max_filter_nest_level), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - uint64_t - config_get_ndn_cache_size() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- -- return __atomic_load_8(&(slapdFrontendConfig->ndn_cache_max_size), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ndn_cache_max_size), __ATOMIC_ACQUIRE, ATOMIC_LONG); - } - - int32_t - config_get_ndn_cache_enabled() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ndn_cache_enabled), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ndn_cache_enabled), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_return_orig_type_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->return_orig_type), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->return_orig_type), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - char * -@@ -6786,7 +6788,7 @@ int32_t - config_get_force_sasl_external(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->force_sasl_external), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->force_sasl_external), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t -@@ -6808,7 +6810,7 @@ int32_t - config_get_entryusn_global(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->entryusn_global), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->entryusn_global), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t -@@ -7046,21 +7048,21 @@ int32_t - config_get_enable_turbo_mode(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->enable_turbo_mode), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->enable_turbo_mode), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_connection_nocanon(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->connection_nocanon), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->connection_nocanon), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_plugin_logging(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->plugin_logging), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->plugin_logging), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t -@@ -7073,21 +7075,21 @@ int32_t - config_get_unhashed_pw_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->unhashed_pw_switch), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->unhashed_pw_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_ignore_time_skew(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->ignore_time_skew), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->ignore_time_skew), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t - config_get_global_backend_lock() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return __atomic_load_4(&(slapdFrontendConfig->global_backend_lock), __ATOMIC_ACQUIRE); -+ return slapi_atomic_load(&(slapdFrontendConfig->global_backend_lock), __ATOMIC_ACQUIRE, ATOMIC_INT); - } - - int32_t -@@ -7163,8 +7165,9 @@ config_get_connection_buffer(void) - int - config_set_connection_buffer(const char *attrname, char *value, char *errorbuf, int apply) - { -- int retVal = LDAP_SUCCESS; - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -+ int retVal = LDAP_SUCCESS; -+ int32_t val; - - if (config_value_is_null(attrname, value, errorbuf, 0)) { - return LDAP_OPERATIONS_ERROR; -@@ -7181,7 +7184,9 @@ config_set_connection_buffer(const char *attrname, char *value, char *errorbuf, - return retVal; - } - -- __atomic_store_4(&(slapdFrontendConfig->connection_buffer), atoi(value), __ATOMIC_RELEASE); -+ val = atoi(value); -+ slapi_atomic_store(&(slapdFrontendConfig->connection_buffer), &val, __ATOMIC_RELEASE, ATOMIC_INT); -+ - return retVal; - } - -@@ -7204,7 +7209,7 @@ config_set_listen_backlog_size(const char *attrname, char *value, char *errorbuf - } - - if (apply) { -- __atomic_store_4(&(slapdFrontendConfig->listen_backlog_size), size, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->listen_backlog_size), &size, __ATOMIC_RELEASE, ATOMIC_INT); - } - return LDAP_SUCCESS; - } -@@ -7617,7 +7622,7 @@ config_set_accesslog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- __atomic_store_4(&(slapdFrontendConfig->accesslog_logging_enabled), value, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->accesslog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); - if (value) { - log_set_logging(CONFIG_ACCESSLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_ACCESS_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7635,7 +7640,7 @@ config_set_auditlog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- __atomic_store_4(&(slapdFrontendConfig->auditlog_logging_enabled), value, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->auditlog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); - if (value) { - log_set_logging(CONFIG_AUDITLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_AUDIT_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7653,7 +7658,7 @@ config_set_auditfaillog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- __atomic_store_4(&(slapdFrontendConfig->auditfaillog_logging_enabled), value, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->auditfaillog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); - if (value) { - log_set_logging(CONFIG_AUDITFAILLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_AUDITFAIL_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7744,7 +7749,7 @@ config_set_malloc_mxfast(const char *attrname, char *value, char *errorbuf, int - value, CONFIG_MALLOC_MXFAST, max); - return LDAP_OPERATIONS_ERROR; - } -- __atomic_store_4(&(slapdFrontendConfig->malloc_mxfast), mxfast, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->malloc_mxfast), &mxfast, __ATOMIC_RELEASE, ATOMIC_INT); - - if ((mxfast >= 0) && (mxfast <= max)) { - mallopt(M_MXFAST, mxfast); -@@ -7784,7 +7789,7 @@ config_set_malloc_trim_threshold(const char *attrname, char *value, char *errorb - return LDAP_OPERATIONS_ERROR; - } - -- __atomic_store_4(&(slapdFrontendConfig->malloc_trim_threshold), trim_threshold, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->malloc_trim_threshold), &trim_threshold, __ATOMIC_RELEASE, ATOMIC_INT); - - if (trim_threshold >= -1) { - mallopt(M_TRIM_THRESHOLD, trim_threshold); -@@ -7831,7 +7836,7 @@ config_set_malloc_mmap_threshold(const char *attrname, char *value, char *errorb - return LDAP_OPERATIONS_ERROR; - } - -- __atomic_store_4(&(slapdFrontendConfig->malloc_mmap_threshold), mmap_threshold, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(slapdFrontendConfig->malloc_mmap_threshold), &mmap_threshold, __ATOMIC_RELEASE, ATOMIC_INT); - - if ((mmap_threshold >= 0) && (mmap_threshold <= max)) { - mallopt(M_MMAP_THRESHOLD, mmap_threshold); -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index 41b5c99..4d44c87 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -4942,12 +4942,13 @@ static LogBufferInfo * - log_create_buffer(size_t sz) - { - LogBufferInfo *lbi; -+ uint64_t init_val = 0; - - lbi = (LogBufferInfo *)slapi_ch_malloc(sizeof(LogBufferInfo)); - lbi->top = (char *)slapi_ch_malloc(sz); - lbi->current = lbi->top; - lbi->maxsize = sz; -- __atomic_store_8(&(lbi->refcount), 0, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(lbi->refcount), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); - return lbi; - } - -@@ -5009,7 +5010,7 @@ log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_t size1, cha - insert_point = lbi->current; - lbi->current += size; - /* Increment the copy refcount */ -- __atomic_add_fetch_8(&(lbi->refcount), 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&(lbi->refcount), __ATOMIC_RELEASE, ATOMIC_LONG); - PR_Unlock(lbi->lock); - - /* Now we can copy without holding the lock */ -@@ -5017,7 +5018,7 @@ log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_t size1, cha - memcpy(insert_point + size1, msg2, size2); - - /* Decrement the copy refcount */ -- __atomic_sub_fetch_8(&(lbi->refcount), 1, __ATOMIC_RELEASE); -+ slapi_atomic_decr(&(lbi->refcount), __ATOMIC_RELEASE, ATOMIC_LONG); - - /* If we are asked to sync to disk immediately, do so */ - if (!slapdFrontendConfig->accesslogbuffering) { -@@ -5037,7 +5038,7 @@ log_flush_buffer(LogBufferInfo *lbi, int type, int sync_now) - if (type == SLAPD_ACCESS_LOG) { - - /* It is only safe to flush once any other threads which are copying are finished */ -- while (__atomic_load_8(&(lbi->refcount), __ATOMIC_ACQUIRE) > 0) { -+ while (slapi_atomic_load(&(lbi->refcount), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { - /* It's ok to sleep for a while because we only flush every second or so */ - DS_Sleep(PR_MillisecondsToInterval(1)); - } -diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c -index 651d70e..6621ceb 100644 ---- a/ldap/servers/slapd/mapping_tree.c -+++ b/ldap/servers/slapd/mapping_tree.c -@@ -1647,7 +1647,7 @@ mapping_tree_init() - - /* we call this function from a single thread, so it should be ok */ - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown has been detected */ - return 0; - } -@@ -1759,6 +1759,8 @@ mtn_free_node(mapping_tree_node **node) - void - mapping_tree_free() - { -+ int init_val = 1; -+ - /* unregister dse callbacks */ - slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, MAPPING_TREE_BASE_DN, LDAP_SCOPE_BASE, "(objectclass=*)", mapping_tree_entry_modify_callback); - slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, MAPPING_TREE_BASE_DN, LDAP_SCOPE_BASE, "(objectclass=*)", mapping_tree_entry_add_callback); -@@ -1771,7 +1773,7 @@ mapping_tree_free() - slapi_unregister_backend_state_change_all(); - /* recursively free tree nodes */ - mtn_free_node(&mapping_tree_root); -- __atomic_store_4(&mapping_tree_freed, 1, __ATOMIC_RELAXED); -+ slapi_atomic_store(&mapping_tree_freed, &init_val, __ATOMIC_RELAXED, ATOMIC_INT); - } - - /* This function returns the first node to parse when a search is done -@@ -2022,7 +2024,7 @@ slapi_dn_write_needs_referral(Slapi_DN *target_sdn, Slapi_Entry **referral) - mapping_tree_node *target_node = NULL; - int ret = 0; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - goto done; - } -@@ -2093,7 +2095,7 @@ slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry **re - int fixup = 0; - - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return LDAP_OPERATIONS_ERROR; - } -@@ -2198,7 +2200,7 @@ slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list, Slapi_E - int flag_partial_result = 0; - int op_type; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - return LDAP_OPERATIONS_ERROR; - } - -@@ -2358,7 +2360,7 @@ slapi_mapping_tree_select_and_check(Slapi_PBlock *pb, char *newdn, Slapi_Backend - int ret; - int need_unlock = 0; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - return LDAP_OPERATIONS_ERROR; - } - -@@ -2524,7 +2526,7 @@ mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, Slapi_Backend **be, - int flag_stop = 0; - struct slapi_componentid *cid = NULL; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shut down detected */ - return LDAP_OPERATIONS_ERROR; - } -@@ -2712,7 +2714,7 @@ best_matching_child(mapping_tree_node *parent, - mapping_tree_node *highest_match_node = NULL; - mapping_tree_node *current; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -@@ -2739,7 +2741,7 @@ mtn_get_mapping_tree_node_by_entry(mapping_tree_node *node, const Slapi_DN *dn) - { - mapping_tree_node *found_node = NULL; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -@@ -2782,7 +2784,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 (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -@@ -2816,7 +2818,7 @@ get_mapping_tree_node_by_name(mapping_tree_node *node, char *be_name) - int i; - mapping_tree_node *found_node = NULL; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -@@ -2863,7 +2865,7 @@ slapi_get_mapping_tree_node_configdn(const Slapi_DN *root) - { - char *dn = NULL; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -@@ -2890,7 +2892,7 @@ slapi_get_mapping_tree_node_configsdn(const Slapi_DN *root) - char *dn = NULL; - Slapi_DN *sdn = NULL; - -- if (__atomic_load_4(&mapping_tree_freed, __ATOMIC_RELAXED)) { -+ if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { - /* shutdown detected */ - return NULL; - } -diff --git a/ldap/servers/slapd/object.c b/ldap/servers/slapd/object.c -index 84845d3..6a1a9a5 100644 ---- a/ldap/servers/slapd/object.c -+++ b/ldap/servers/slapd/object.c -@@ -43,10 +43,12 @@ Object * - object_new(void *user_data, FNFree destructor) - { - Object *o; -+ uint64_t init_val = 1; -+ - o = (object *)slapi_ch_malloc(sizeof(object)); - o->destructor = destructor; - o->data = user_data; -- __atomic_store_8(&(o->refcnt), 1, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(o->refcnt), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); - return o; - } - -@@ -60,7 +62,7 @@ void - object_acquire(Object *o) - { - PR_ASSERT(NULL != o); -- __atomic_add_fetch_8(&(o->refcnt), 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&(o->refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); - } - - -@@ -75,7 +77,7 @@ object_release(Object *o) - PRInt32 refcnt_after_release; - - PR_ASSERT(NULL != o); -- refcnt_after_release = __atomic_sub_fetch_8(&(o->refcnt), 1, __ATOMIC_ACQ_REL); -+ refcnt_after_release = slapi_atomic_decr(&(o->refcnt), __ATOMIC_ACQ_REL, ATOMIC_LONG); - if (refcnt_after_release == 0) { - /* Object can be destroyed */ - if (o->destructor) -diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c -index 0489122..70c530b 100644 ---- a/ldap/servers/slapd/psearch.c -+++ b/ldap/servers/slapd/psearch.c -@@ -134,7 +134,7 @@ ps_stop_psearch_system() - if (PS_IS_INITIALIZED()) { - PSL_LOCK_WRITE(); - for (ps = psearch_list->pl_head; NULL != ps; ps = ps->ps_next) { -- __atomic_add_fetch_8(&(ps->ps_complete), 1, __ATOMIC_RELEASE); -+ slapi_atomic_incr(&(ps->ps_complete), __ATOMIC_RELEASE, ATOMIC_LONG); - } - PSL_UNLOCK_WRITE(); - ps_wakeup_all(); -@@ -285,7 +285,7 @@ ps_send_results(void *arg) - - PR_Lock(psearch_list->pl_cvarlock); - -- while ((conn_acq_flag == 0) && __atomic_load_8(&(ps->ps_complete), __ATOMIC_ACQUIRE) == 0) { -+ while ((conn_acq_flag == 0) && slapi_atomic_load(&(ps->ps_complete), __ATOMIC_ACQUIRE, ATOMIC_LONG) == 0) { - /* Check for an abandoned operation */ - if (pb_op == NULL || slapi_op_abandoned(ps->ps_pblock)) { - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", -@@ -427,6 +427,7 @@ static PSearch * - psearch_alloc(void) - { - PSearch *ps; -+ uint64_t init_val = 0; - - ps = (PSearch *)slapi_ch_calloc(1, sizeof(PSearch)); - -@@ -437,7 +438,7 @@ psearch_alloc(void) - slapi_ch_free((void **)&ps); - return (NULL); - } -- __atomic_store_8(&(ps->ps_complete), 0, __ATOMIC_RELEASE); -+ slapi_atomic_store(&(ps->ps_complete), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); - ps->ps_eq_head = ps->ps_eq_tail = (PSEQNode *)NULL; - ps->ps_lasttime = (time_t)0L; - ps->ps_next = NULL; -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index 3397c63..c434add 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -8202,6 +8202,58 @@ void slapi_operation_time_initiated(Slapi_Operation *o, struct timespec *initiat - */ - #endif - -+/* See: https://gcc.gnu.org/ml/gcc/2016-11/txt6ZlA_JS27i.txt */ -+#define ATOMIC_GENERIC 0 -+#define ATOMIC_INT 4 -+#define ATOMIC_LONG 8 -+#define ATOMIC_INT128 16 /* Future */ -+ -+/** -+ * Store an integral value atomicly -+ * -+ * \param ptr - integral pointer -+ * \param val - pointer to integral value (use integral type int32_t with ATOMIC_INT, or uint64_t -+ * with ATOMIC_LONG & ATOMIC_GENERIC) -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG -+ */ -+void slapi_atomic_store(void *ptr, void *val, int memorder, int type); -+ -+/** -+ * Get an integral value atomicly -+ * -+ * \param ptr - integral pointer -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG -+ * \return - -+ */ -+uint64_t slapi_atomic_load(void *ptr, int memorder, int type); -+ -+/** -+ * Increment integral atomicly -+ * -+ * \param ptr - pointer to integral to increment -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG -+ * \return - new value of ptr -+ */ -+uint64_t slapi_atomic_incr(void *ptr, int memorder, int type); -+ -+/** -+ * Decrement integral atomicly -+ * -+ * \param ptr - pointer to integral to decrement -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG -+ * \return - new value of ptr -+ */ -+uint64_t slapi_atomic_decr(void *ptr, int memorder, int type); -+ -+ - #ifdef __cplusplus - } - #endif -diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c -index ba0091f..9e705b3 100644 ---- a/ldap/servers/slapd/slapi_counter.c -+++ b/ldap/servers/slapd/slapi_counter.c -@@ -283,3 +283,103 @@ slapi_counter_get_value(Slapi_Counter *counter) - - return value; - } -+ -+ -+/* -+ * -+ * Atomic functions -+ * -+ * ptr - a pointer to an integral type variable: int, uint32_t, uint64_t, etc -+ * -+ * memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, or __ATOMIC_SEQ_CST -+ * -+ * See: https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/_005f_005fatomic-Builtins.html -+ * -+ * type_size - ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG, see slapi-plugin.h for more info -+ * -+ * Future: -+ * If we need to support ATOMIC_INT128 (not available on 32bit systems): -+ * __atomic_store_16((uint64_t *)&ptr, val, memorder); -+ * __atomic_load_16((uint64_t *)&ptr, memorder); -+ * __atomic_add_fetch_16((uint64_t *)&ptr, 1, memorder); -+ * __atomic_sub_fetch_16((uint64_t *)&ptr, 1, memorder); -+ */ -+ -+/* -+ * "val" must be either int32_t or uint64_t -+ */ -+void -+slapi_atomic_store(void *ptr, void *val, int memorder, int type_size) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ if (type_size == ATOMIC_INT) { -+ __atomic_store_4((int32_t *)ptr, *(int32_t *)val, memorder); -+ } else if (type_size == ATOMIC_LONG) { -+ __atomic_store_8((uint64_t *)ptr, *(uint64_t *)val, memorder); -+ } else { -+ /* ATOMIC_GENERIC or unknown size */ -+ __atomic_store((uint64_t *)&ptr, (uint64_t *)val, memorder); -+ } -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ PR_AtomicSet(pr_ptr, *(PRInt32 *)val); -+#endif -+} -+ -+uint64_t -+slapi_atomic_load(void *ptr, int memorder, int type_size) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ uint64_t ret; -+ -+ if (type_size == ATOMIC_INT) { -+ return __atomic_load_4((int32_t *)ptr, memorder); -+ } else if (type_size == ATOMIC_LONG) { -+ return __atomic_load_8((uint64_t *)ptr, memorder); -+ } else { -+ /* ATOMIC_GENERIC or unknown size */ -+ __atomic_load((uint64_t *)ptr, &ret, memorder); -+ return ret; -+ } -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicAdd(pr_ptr, 0); -+#endif -+} -+ -+uint64_t -+slapi_atomic_incr(void *ptr, int memorder, int type_size) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ if (type_size == ATOMIC_INT) { -+ return __atomic_add_fetch_4((int32_t *)ptr, 1, memorder); -+ } else if (type_size == ATOMIC_LONG) { -+ return __atomic_add_fetch_8((uint64_t *)ptr, 1, memorder); -+ } else { -+ /* ATOMIC_GENERIC or unknown size */ -+ return __atomic_add_fetch((uint64_t *)ptr, 1, memorder); -+ } -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicIncrement(pr_ptr); -+#endif -+} -+ -+uint64_t -+slapi_atomic_decr(void *ptr, int memorder, int type_size) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ if (type_size == ATOMIC_INT) { -+ return __atomic_sub_fetch_4((int32_t *)ptr, 1, memorder); -+ } else if (type_size == ATOMIC_LONG) { -+ return __atomic_sub_fetch_8((uint64_t *)ptr, 1, memorder); -+ } else { -+ /* ATOMIC_GENERIC or unknown size */ -+ return __atomic_sub_fetch((uint64_t *)ptr, 1, memorder); -+ } -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicDecrement(pr_ptr); -+#endif -+} -diff --git a/ldap/servers/slapd/thread_data.c b/ldap/servers/slapd/thread_data.c -index 9964832..d473710 100644 ---- a/ldap/servers/slapd/thread_data.c -+++ b/ldap/servers/slapd/thread_data.c -@@ -9,7 +9,7 @@ - /* - * Thread Local Storage Functions - */ --#include -+#include "slap.h" - #include - - void td_dn_destructor(void *priv); -diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c -index 7921cbc..2ad0bd7 100644 ---- a/src/nunc-stans/ns/ns_thrpool.c -+++ b/src/nunc-stans/ns/ns_thrpool.c -@@ -169,7 +169,11 @@ int32_t - ns_thrpool_is_shutdown(struct ns_thrpool_t *tp) - { - int32_t result = 0; -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_load(&(tp->shutdown), &result, __ATOMIC_ACQUIRE); -+#else -+ result = PR_AtomicAdd(&(tp->shutdown), 0); -+#endif - return result; - } - -@@ -177,7 +181,11 @@ int32_t - ns_thrpool_is_event_shutdown(struct ns_thrpool_t *tp) - { - int32_t result = 0; -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_load(&(tp->shutdown_event_loop), &result, __ATOMIC_ACQUIRE); -+#else -+ result = PR_AtomicAdd(&(tp->shutdown_event_loop), 0); -+#endif - return result; - } - -@@ -1442,8 +1450,11 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp) - #endif - if (tp) { - /* Set the flag to shutdown the event loop. */ -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&(tp->shutdown_event_loop), 1, __ATOMIC_RELEASE); -- -+#else -+ PR_AtomicIncrement(&(tp->shutdown_event_loop)); -+#endif - /* Finish the event queue wakeup job. This has the - * side effect of waking up the event loop thread, which - * will cause it to exit since we set the event loop -@@ -1532,7 +1543,11 @@ 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. */ -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&(tp->shutdown), 1, __ATOMIC_RELEASE); -+#else -+ PR_AtomicIncrement(&(tp->shutdown)); -+#endif - - /* Send worker shutdown jobs into the queues. This allows - * currently queued jobs to complete. -diff --git a/src/nunc-stans/test/test_nuncstans_stress_core.c b/src/nunc-stans/test/test_nuncstans_stress_core.c -index a678800..2fc4ef4 100644 ---- a/src/nunc-stans/test/test_nuncstans_stress_core.c -+++ b/src/nunc-stans/test/test_nuncstans_stress_core.c -@@ -128,7 +128,11 @@ server_conn_write(struct ns_job_t *job) - assert(connctx != NULL); - if (NS_JOB_IS_TIMER(ns_job_get_output_type(job))) { - do_logging(LOG_ERR, "conn_write: job [%p] timeout\n", job); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&server_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&server_fail_count); -+#endif - conn_ctx_free(connctx); - assert_int_equal(ns_job_done(job), 0); - return; -@@ -173,7 +177,11 @@ server_conn_read(struct ns_job_t *job) - if (NS_JOB_IS_TIMER(ns_job_get_output_type(job))) { - /* The event that triggered this call back is because we timed out waiting for IO */ - do_logging(LOG_ERR, "conn_read: job [%p] timed out\n", job); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&server_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&server_fail_count); -+#endif - conn_ctx_free(connctx); - assert_int_equal(ns_job_done(job), 0); - return; -@@ -204,7 +212,11 @@ server_conn_read(struct ns_job_t *job) - return; - } else { - do_logging(LOG_ERR, "conn_read: read error for job [%p] %d: %s\n", job, PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&server_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&server_fail_count); -+#endif - conn_ctx_free(connctx); - assert_int_equal(ns_job_done(job), 0); - return; -@@ -214,7 +226,11 @@ server_conn_read(struct ns_job_t *job) - /* Didn't read anything */ - do_logging(LOG_DEBUG, "conn_read: job [%p] closed\n", job); - /* Increment the success */ -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&server_success_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&server_success_count); -+#endif - conn_ctx_free(connctx); - assert_int_equal(ns_job_done(job), 0); - return; -@@ -314,26 +330,41 @@ client_response_cb(struct ns_job_t *job) - if (len < 0) { - /* PRErrorCode prerr = PR_GetError(); */ - do_logging(LOG_ERR, "FAIL: connection error, no data \n"); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&client_fail_count); -+#endif - goto done; - } else if (len == 0) { - do_logging(LOG_ERR, "FAIL: connection closed, no data \n"); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&client_fail_count); -+#endif - goto done; - } else { - /* Be paranoid, force last byte null */ - buffer[buflen - 1] = '\0'; - if (strncmp("this is a test!\n", buffer, strlen("this is a test!\n")) != 0) { - do_logging(LOG_ERR, "FAIL: connection incorrect response, no data \n"); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&client_fail_count); -+#endif - goto done; - } - } - - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); -- -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_success_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&client_success_count); -+#endif - do_logging(LOG_ERR, "PASS: %ld.%ld %d\n", ts.tv_sec, ts.tv_nsec, client_success_count); - - done: -@@ -354,7 +385,11 @@ client_initiate_connection_cb(struct ns_job_t *job) - char *err = NULL; - PR_GetErrorText(err); - do_logging(LOG_ERR, "FAIL: Socket failed, %d -> %s\n", PR_GetError(), err); -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_fail_count, 1, __ATOMIC_SEQ_CST); -+#else -+ PR_AtomicIncrement(&client_fail_count); -+#endif - goto done; - } - -@@ -368,8 +403,11 @@ client_initiate_connection_cb(struct ns_job_t *job) - PR_GetErrorText(err); - do_logging(LOG_ERR, "FAIL: cannot connect, timeout %d -> %s \n", PR_GetError(), err); - /* Atomic increment fail */ -+#ifdef ATOMIC_64BIT_OPERATIONS - __atomic_add_fetch(&client_timeout_count, 1, __ATOMIC_SEQ_CST); -- -+#else -+ PR_AtomicIncrement(&client_timeout_count); -+#endif - if (sock != NULL) { - PR_Close(sock); - } --- -2.9.5 - diff --git a/SOURCES/0001-Issue-49170-sync-plugin-thread-count-not-handled-cor.patch b/SOURCES/0001-Issue-49170-sync-plugin-thread-count-not-handled-cor.patch new file mode 100644 index 0000000..28d65ec --- /dev/null +++ b/SOURCES/0001-Issue-49170-sync-plugin-thread-count-not-handled-cor.patch @@ -0,0 +1,71 @@ +From a00917eec0bcef75180eaf4dd9b360519b9e2644 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0001-Ticket-49305-Need-to-wrap-atomic-calls.patch b/SOURCES/0001-Ticket-49305-Need-to-wrap-atomic-calls.patch deleted file mode 100644 index 93820e4..0000000 --- a/SOURCES/0001-Ticket-49305-Need-to-wrap-atomic-calls.patch +++ /dev/null @@ -1,1325 +0,0 @@ -From 76e8c99e00f776fdab6cf834923d19f911f06fb9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 28 Sep 2017 10:38:20 -0400 -Subject: [PATCH] Ticket 49305 - Need to wrap atomic calls - -Bug Description: Some RHEL 7.5 platforms (ppc 32bit) still do not support - all the gcc built-in atomics. This breaks the downstream - builds. - -Fix Description: Use wrapper functions for the atomic's using #define's - to detect if builtin atomics are supported, otherwise - use the generic nspr atomic functions. - -https://pagure.io/389-ds-base/issue/49305 - -Reviewed by: tbordaz, lkrispen, and wibrown(Thanks!!!) - -(cherry picked from commit 93a29584ddae52497b898b451c2c810244627acb) ---- - ldap/servers/slapd/attrsyntax.c | 8 +- - ldap/servers/slapd/back-ldbm/dblayer.c | 8 +- - ldap/servers/slapd/entry.c | 8 +- - ldap/servers/slapd/libglobs.c | 154 ++++++++++++++++----------------- - ldap/servers/slapd/log.c | 9 +- - ldap/servers/slapd/mapping_tree.c | 28 +++--- - ldap/servers/slapd/object.c | 7 +- - ldap/servers/slapd/psearch.c | 7 +- - ldap/servers/slapd/slapi-plugin.h | 65 ++++++++++---- - ldap/servers/slapd/slapi_counter.c | 113 +++++++++++++----------- - 10 files changed, 223 insertions(+), 184 deletions(-) - -diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c -index a0a60c4..1a9efef 100644 ---- a/ldap/servers/slapd/attrsyntax.c -+++ b/ldap/servers/slapd/attrsyntax.c -@@ -274,7 +274,7 @@ attr_syntax_get_by_oid_locking_optional(const char *oid, PRBool use_lock, PRUint - } - asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, oid); - if (asi) { -- slapi_atomic_incr(&(asi->asi_refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(asi->asi_refcnt), __ATOMIC_RELEASE); - } - if (use_lock) { - AS_UNLOCK_READ(oid2asi_lock); -@@ -371,7 +371,7 @@ attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock, PRUi - } - asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, name); - if (NULL != asi) { -- slapi_atomic_incr(&(asi->asi_refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(asi->asi_refcnt), __ATOMIC_RELEASE); - } - if (use_lock) { - AS_UNLOCK_READ(name2asi_lock); -@@ -406,7 +406,7 @@ attr_syntax_return_locking_optional(struct asyntaxinfo *asi, PRBool use_lock) - } - if (NULL != asi) { - PRBool delete_it = PR_FALSE; -- if (0 == slapi_atomic_decr(&(asi->asi_refcnt), __ATOMIC_ACQ_REL, ATOMIC_LONG)) { -+ if (0 == slapi_atomic_decr_64(&(asi->asi_refcnt), __ATOMIC_ACQ_REL)) { - delete_it = asi->asi_marked_for_delete; - } - -@@ -540,7 +540,7 @@ attr_syntax_delete_no_lock(struct asyntaxinfo *asi, - PL_HashTableRemove(ht, asi->asi_aliases[i]); - } - } -- if (slapi_atomic_load(&(asi->asi_refcnt), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { -+ if (slapi_atomic_load_64(&(asi->asi_refcnt), __ATOMIC_ACQUIRE) > 0) { - asi->asi_marked_for_delete = PR_TRUE; - } else { - /* This is ok, but the correct thing is to call delete first, -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index c4c4959..9e557a2 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -2880,7 +2880,7 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - /* it's like a semaphore -- when count > 0, any file handle that's in - * the attrinfo will remain valid from here on. - */ -- slapi_atomic_incr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(a->ai_dblayer_count), __ATOMIC_RELEASE); - - if (a->ai_dblayer && ((dblayer_handle *)(a->ai_dblayer))->dblayer_dbp) { - /* This means that the pointer is valid, so we should return it. */ -@@ -2938,7 +2938,7 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - /* some sort of error -- we didn't open a handle at all. - * decrement the refcount back to where it was. - */ -- slapi_atomic_decr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_decr_64(&(a->ai_dblayer_count), __ATOMIC_RELEASE); - } - - return return_value; -@@ -2950,7 +2950,7 @@ dblayer_get_index_file(backend *be, struct attrinfo *a, DB **ppDB, int open_flag - int - dblayer_release_index_file(backend *be __attribute__((unused)), struct attrinfo *a, DB *pDB __attribute__((unused))) - { -- slapi_atomic_decr(&(a->ai_dblayer_count), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_decr_64(&(a->ai_dblayer_count), __ATOMIC_RELEASE); - return 0; - } - -@@ -3057,7 +3057,7 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in - - dblayer_release_index_file(be, a, db); - -- while (slapi_atomic_load(&(a->ai_dblayer_count), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { -+ while (slapi_atomic_load_64(&(a->ai_dblayer_count), __ATOMIC_ACQUIRE) > 0) { - /* someone is using this index file */ - /* ASSUMPTION: you have already set the INDEX_OFFLINE flag, because - * you intend to mess with this index. therefore no new requests -diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c -index 289a149..fbbc8fa 100644 ---- a/ldap/servers/slapd/entry.c -+++ b/ldap/servers/slapd/entry.c -@@ -2249,14 +2249,14 @@ static int32_t g_virtual_watermark = 0; /* good enough to init */ - int - slapi_entry_vattrcache_watermark_isvalid(const Slapi_Entry *e) - { -- return e->e_virtual_watermark == slapi_atomic_load(&g_virtual_watermark, __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return e->e_virtual_watermark == slapi_atomic_load_32(&g_virtual_watermark, __ATOMIC_ACQUIRE); - - } - - void - slapi_entry_vattrcache_watermark_set(Slapi_Entry *e) - { -- e->e_virtual_watermark = slapi_atomic_load(&g_virtual_watermark, __ATOMIC_ACQUIRE, ATOMIC_INT); -+ e->e_virtual_watermark = slapi_atomic_load_32(&g_virtual_watermark, __ATOMIC_ACQUIRE); - } - - void -@@ -2269,8 +2269,8 @@ void - slapi_entrycache_vattrcache_watermark_invalidate() - { - /* Make sure the value is never 0 */ -- if (slapi_atomic_incr(&g_virtual_watermark, __ATOMIC_RELEASE, ATOMIC_INT) == 0) { -- slapi_atomic_incr(&g_virtual_watermark, __ATOMIC_RELEASE, ATOMIC_INT); -+ if (slapi_atomic_incr_32(&g_virtual_watermark, __ATOMIC_RELEASE) == 0) { -+ slapi_atomic_incr_32(&g_virtual_watermark, __ATOMIC_RELEASE); - } - } - -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index 4c54cf7..1ba3000 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -1335,19 +1335,19 @@ static uint64_t active_threads = 0; - void - g_incr_active_threadcnt(void) - { -- slapi_atomic_incr(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&active_threads, __ATOMIC_RELEASE); - } - - void - g_decr_active_threadcnt(void) - { -- slapi_atomic_decr(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_decr_64(&active_threads, __ATOMIC_RELEASE); - } - - uint64_t - g_get_active_threadcnt(void) - { -- return slapi_atomic_load(&active_threads, __ATOMIC_RELEASE, ATOMIC_LONG); -+ return slapi_atomic_load_64(&active_threads, __ATOMIC_RELEASE); - } - - /* -@@ -1936,7 +1936,7 @@ config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, - size = NDN_DEFAULT_SIZE; - } - if (apply) { -- slapi_atomic_store(&(slapdFrontendConfig->ndn_cache_max_size), &size, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_store_64(&(slapdFrontendConfig->ndn_cache_max_size), size, __ATOMIC_RELEASE); - } - - return retVal; -@@ -3476,7 +3476,7 @@ int32_t - config_get_dynamic_plugins(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->dynamic_plugins), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->dynamic_plugins), __ATOMIC_ACQUIRE); - - } - -@@ -3499,7 +3499,7 @@ int32_t - config_get_cn_uses_dn_syntax_in_dns() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->cn_uses_dn_syntax_in_dns), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->cn_uses_dn_syntax_in_dns), __ATOMIC_ACQUIRE); - } - - int32_t -@@ -3544,7 +3544,7 @@ config_set_onoff(const char *attrname, char *value, int32_t *configvalue, char * - newval = LDAP_OFF; - } - -- slapi_atomic_store(configvalue, &newval, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(configvalue, newval, __ATOMIC_RELEASE); - - return retVal; - } -@@ -3916,7 +3916,7 @@ config_set_threadnumber(const char *attrname, char *value, char *errorbuf, int a - retVal = LDAP_OPERATIONS_ERROR; - } - if (apply) { -- slapi_atomic_store(&(slapdFrontendConfig->threadnumber), &threadnum, __ATOMIC_RELAXED, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->threadnumber), threadnum, __ATOMIC_RELAXED); - } - return retVal; - } -@@ -3925,7 +3925,7 @@ int - config_set_maxthreadsperconn(const char *attrname, char *value, char *errorbuf, int apply) - { - int retVal = LDAP_SUCCESS; -- long maxthreadnum = 0; -+ int32_t maxthreadnum = 0; - char *endp = NULL; - - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -@@ -3935,7 +3935,7 @@ config_set_maxthreadsperconn(const char *attrname, char *value, char *errorbuf, - } - - errno = 0; -- maxthreadnum = strtol(value, &endp, 10); -+ maxthreadnum = (int32_t)strtol(value, &endp, 10); - - if (*endp != '\0' || errno == ERANGE || maxthreadnum < 1 || maxthreadnum > 65535) { - slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, -@@ -3945,7 +3945,7 @@ config_set_maxthreadsperconn(const char *attrname, char *value, char *errorbuf, - } - - if (apply) { -- slapi_atomic_store(&(slapdFrontendConfig->maxthreadsperconn), &maxthreadnum, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->maxthreadsperconn), maxthreadnum, __ATOMIC_RELEASE); - } - return retVal; - } -@@ -4083,7 +4083,7 @@ int - config_set_ioblocktimeout(const char *attrname, char *value, char *errorbuf, int apply) - { - int retVal = LDAP_SUCCESS; -- long nValue = 0; -+ int32_t nValue = 0; - char *endp = NULL; - - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -@@ -4093,7 +4093,7 @@ config_set_ioblocktimeout(const char *attrname, char *value, char *errorbuf, int - } - - errno = 0; -- nValue = strtol(value, &endp, 10); -+ nValue = (int32_t)strtol(value, &endp, 10); - - if (*endp != '\0' || errno == ERANGE || nValue < 0) { - slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: invalid value \"%s\", I/O block timeout must range from 0 to %lld", -@@ -4103,7 +4103,7 @@ config_set_ioblocktimeout(const char *attrname, char *value, char *errorbuf, int - } - - if (apply) { -- slapi_atomic_store(&(slapdFrontendConfig->ioblocktimeout), &nValue, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->ioblocktimeout), nValue, __ATOMIC_RELEASE); - } - return retVal; - } -@@ -4607,7 +4607,7 @@ int32_t - config_get_sasl_mapping_fallback() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->sasl_mapping_fallback), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->sasl_mapping_fallback), __ATOMIC_ACQUIRE); - - } - -@@ -4615,14 +4615,14 @@ int32_t - config_get_disk_monitoring() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->disk_monitoring), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->disk_monitoring), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_disk_logging_critical() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->disk_logging_critical), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->disk_logging_critical), __ATOMIC_ACQUIRE); - } - - int -@@ -4669,14 +4669,14 @@ int32_t - config_get_ldapi_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ldapi_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ldapi_switch), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_ldapi_bind_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ldapi_bind_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ldapi_bind_switch), __ATOMIC_ACQUIRE); - } - - char * -@@ -4695,7 +4695,7 @@ int - config_get_ldapi_map_entries() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ldapi_map_entries), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ldapi_map_entries), __ATOMIC_ACQUIRE); - } - - char * -@@ -4765,7 +4765,7 @@ int32_t - config_get_slapi_counters() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->slapi_counters), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->slapi_counters), __ATOMIC_ACQUIRE); - - } - -@@ -4948,7 +4948,7 @@ int32_t - config_get_pw_change(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_change), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_change), __ATOMIC_ACQUIRE); - } - - -@@ -4956,7 +4956,7 @@ int32_t - config_get_pw_history(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_history), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_history), __ATOMIC_ACQUIRE); - } - - -@@ -4964,21 +4964,21 @@ int32_t - config_get_pw_must_change(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_must_change), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_must_change), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_allow_hashed_pw(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->allow_hashed_pw), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->allow_hashed_pw), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_pw_syntax(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_syntax), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_syntax), __ATOMIC_ACQUIRE); - } - - -@@ -5167,21 +5167,21 @@ int32_t - config_get_pw_is_global_policy(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_is_global_policy), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_is_global_policy), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_pw_is_legacy_policy(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_is_legacy), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_is_legacy), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_pw_exp(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_exp), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_exp), __ATOMIC_ACQUIRE); - } - - -@@ -5189,14 +5189,14 @@ int32_t - config_get_pw_unlock(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_unlock), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_unlock), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_pw_lockout() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->pw_policy.pw_lockout), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->pw_policy.pw_lockout), __ATOMIC_ACQUIRE); - } - - int -@@ -5216,112 +5216,112 @@ int32_t - config_get_lastmod() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->lastmod), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->lastmod), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_enquote_sup_oc() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->enquote_sup_oc), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->enquote_sup_oc), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_nagle(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->nagle), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->nagle), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_accesscontrol(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->accesscontrol), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->accesscontrol), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_return_exact_case(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->return_exact_case), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->return_exact_case), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_result_tweak(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->result_tweak), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->result_tweak), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_moddn_aci(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->moddn_aci), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->moddn_aci), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_security(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->security), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->security), __ATOMIC_ACQUIRE); - } - - int32_t - slapi_config_get_readonly(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->readonly), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->readonly), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_schemacheck(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->schemacheck), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->schemacheck), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_schemamod(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->schemamod), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->schemamod), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_syntaxcheck(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->syntaxcheck), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->syntaxcheck), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_syntaxlogging(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->syntaxlogging), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->syntaxlogging), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_dn_validate_strict(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->dn_validate_strict), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->dn_validate_strict), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_ds4_compatible_schema(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ds4_compatible_schema), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ds4_compatible_schema), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_schema_ignore_trailing_spaces(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->schema_ignore_trailing_spaces), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->schema_ignore_trailing_spaces), __ATOMIC_ACQUIRE); - } - - char * -@@ -5405,7 +5405,7 @@ config_get_threadnumber(void) - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); - int32_t retVal; - -- retVal = slapi_atomic_load(&(slapdFrontendConfig->threadnumber), __ATOMIC_RELAXED, ATOMIC_INT); -+ retVal = slapi_atomic_load_32(&(slapdFrontendConfig->threadnumber), __ATOMIC_RELAXED); - - if (retVal <= 0) { - retVal = util_get_hardware_threads(); -@@ -5423,7 +5423,7 @@ int32_t - config_get_maxthreadsperconn() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->maxthreadsperconn), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->maxthreadsperconn), __ATOMIC_ACQUIRE); - } - - int -@@ -5455,7 +5455,7 @@ int32_t - config_get_ioblocktimeout() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ioblocktimeout), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ioblocktimeout), __ATOMIC_ACQUIRE); - } - - int -@@ -5772,21 +5772,21 @@ int32_t - config_get_unauth_binds_switch(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->allow_unauth_binds), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->allow_unauth_binds), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_require_secure_binds(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->require_secure_binds), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->require_secure_binds), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_anon_access_switch(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->allow_anon_access), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->allow_anon_access), __ATOMIC_ACQUIRE); - } - - int -@@ -6028,7 +6028,7 @@ int32_t - config_get_minssf_exclude_rootdse() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->minssf_exclude_rootdse), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->minssf_exclude_rootdse), __ATOMIC_ACQUIRE); - - } - -@@ -6057,7 +6057,7 @@ config_set_max_filter_nest_level(const char *attrname, char *value, char *errorb - return retVal; - } - -- slapi_atomic_store(&(slapdFrontendConfig->max_filter_nest_level), &level, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->max_filter_nest_level), level, __ATOMIC_RELEASE); - return retVal; - } - -@@ -6065,28 +6065,28 @@ int32_t - config_get_max_filter_nest_level() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->max_filter_nest_level), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->max_filter_nest_level), __ATOMIC_ACQUIRE); - } - - uint64_t - config_get_ndn_cache_size() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ndn_cache_max_size), __ATOMIC_ACQUIRE, ATOMIC_LONG); -+ return slapi_atomic_load_64(&(slapdFrontendConfig->ndn_cache_max_size), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_ndn_cache_enabled() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ndn_cache_enabled), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ndn_cache_enabled), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_return_orig_type_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->return_orig_type), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->return_orig_type), __ATOMIC_ACQUIRE); - } - - char * -@@ -6788,7 +6788,7 @@ int32_t - config_get_force_sasl_external(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->force_sasl_external), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->force_sasl_external), __ATOMIC_ACQUIRE); - } - - int32_t -@@ -6810,7 +6810,7 @@ int32_t - config_get_entryusn_global(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->entryusn_global), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->entryusn_global), __ATOMIC_ACQUIRE); - } - - int32_t -@@ -7048,21 +7048,21 @@ int32_t - config_get_enable_turbo_mode(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->enable_turbo_mode), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->enable_turbo_mode), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_connection_nocanon(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->connection_nocanon), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->connection_nocanon), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_plugin_logging(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->plugin_logging), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->plugin_logging), __ATOMIC_ACQUIRE); - } - - int32_t -@@ -7075,21 +7075,21 @@ int32_t - config_get_unhashed_pw_switch() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->unhashed_pw_switch), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->unhashed_pw_switch), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_ignore_time_skew(void) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->ignore_time_skew), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->ignore_time_skew), __ATOMIC_ACQUIRE); - } - - int32_t - config_get_global_backend_lock() - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- return slapi_atomic_load(&(slapdFrontendConfig->global_backend_lock), __ATOMIC_ACQUIRE, ATOMIC_INT); -+ return slapi_atomic_load_32(&(slapdFrontendConfig->global_backend_lock), __ATOMIC_ACQUIRE); - } - - int32_t -@@ -7185,7 +7185,7 @@ config_set_connection_buffer(const char *attrname, char *value, char *errorbuf, - } - - val = atoi(value); -- slapi_atomic_store(&(slapdFrontendConfig->connection_buffer), &val, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->connection_buffer), val, __ATOMIC_RELEASE); - - return retVal; - } -@@ -7209,7 +7209,7 @@ config_set_listen_backlog_size(const char *attrname, char *value, char *errorbuf - } - - if (apply) { -- slapi_atomic_store(&(slapdFrontendConfig->listen_backlog_size), &size, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->listen_backlog_size), size, __ATOMIC_RELEASE); - } - return LDAP_SUCCESS; - } -@@ -7622,7 +7622,7 @@ config_set_accesslog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- slapi_atomic_store(&(slapdFrontendConfig->accesslog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->accesslog_logging_enabled), value, __ATOMIC_RELEASE); - if (value) { - log_set_logging(CONFIG_ACCESSLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_ACCESS_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7640,7 +7640,7 @@ config_set_auditlog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- slapi_atomic_store(&(slapdFrontendConfig->auditlog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->auditlog_logging_enabled), value, __ATOMIC_RELEASE); - if (value) { - log_set_logging(CONFIG_AUDITLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_AUDIT_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7658,7 +7658,7 @@ config_set_auditfaillog_enabled(int value) - char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; - errorbuf[0] = '\0'; - -- slapi_atomic_store(&(slapdFrontendConfig->auditfaillog_logging_enabled), &value, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->auditfaillog_logging_enabled), value, __ATOMIC_RELEASE); - if (value) { - log_set_logging(CONFIG_AUDITFAILLOG_LOGGING_ENABLED_ATTRIBUTE, "on", SLAPD_AUDITFAIL_LOG, errorbuf, CONFIG_APPLY); - } else { -@@ -7736,7 +7736,7 @@ config_set_malloc_mxfast(const char *attrname, char *value, char *errorbuf, int - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); - int max = 80 * (sizeof(size_t) / 4); -- int mxfast; -+ int32_t mxfast; - char *endp = NULL; - - if (config_value_is_null(attrname, value, errorbuf, 0)) { -@@ -7749,7 +7749,7 @@ config_set_malloc_mxfast(const char *attrname, char *value, char *errorbuf, int - value, CONFIG_MALLOC_MXFAST, max); - return LDAP_OPERATIONS_ERROR; - } -- slapi_atomic_store(&(slapdFrontendConfig->malloc_mxfast), &mxfast, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->malloc_mxfast), mxfast, __ATOMIC_RELEASE); - - if ((mxfast >= 0) && (mxfast <= max)) { - mallopt(M_MXFAST, mxfast); -@@ -7775,7 +7775,7 @@ int - config_set_malloc_trim_threshold(const char *attrname, char *value, char *errorbuf, int apply __attribute__((unused))) - { - slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -- int trim_threshold; -+ int32_t trim_threshold; - char *endp = NULL; - - if (config_value_is_null(attrname, value, errorbuf, 0)) { -@@ -7789,7 +7789,7 @@ config_set_malloc_trim_threshold(const char *attrname, char *value, char *errorb - return LDAP_OPERATIONS_ERROR; - } - -- slapi_atomic_store(&(slapdFrontendConfig->malloc_trim_threshold), &trim_threshold, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->malloc_trim_threshold), trim_threshold, __ATOMIC_RELEASE); - - if (trim_threshold >= -1) { - mallopt(M_TRIM_THRESHOLD, trim_threshold); -@@ -7836,7 +7836,7 @@ config_set_malloc_mmap_threshold(const char *attrname, char *value, char *errorb - return LDAP_OPERATIONS_ERROR; - } - -- slapi_atomic_store(&(slapdFrontendConfig->malloc_mmap_threshold), &mmap_threshold, __ATOMIC_RELEASE, ATOMIC_INT); -+ slapi_atomic_store_32(&(slapdFrontendConfig->malloc_mmap_threshold), mmap_threshold, __ATOMIC_RELEASE); - - if ((mmap_threshold >= 0) && (mmap_threshold <= max)) { - mallopt(M_MMAP_THRESHOLD, mmap_threshold); -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index 4d44c87..e16d89c 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -4942,13 +4942,12 @@ static LogBufferInfo * - log_create_buffer(size_t sz) - { - LogBufferInfo *lbi; -- uint64_t init_val = 0; - - lbi = (LogBufferInfo *)slapi_ch_malloc(sizeof(LogBufferInfo)); - lbi->top = (char *)slapi_ch_malloc(sz); - lbi->current = lbi->top; - lbi->maxsize = sz; -- slapi_atomic_store(&(lbi->refcount), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_store_64(&(lbi->refcount), 0, __ATOMIC_RELEASE); - return lbi; - } - -@@ -5010,7 +5009,7 @@ log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_t size1, cha - insert_point = lbi->current; - lbi->current += size; - /* Increment the copy refcount */ -- slapi_atomic_incr(&(lbi->refcount), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(lbi->refcount), __ATOMIC_RELEASE); - PR_Unlock(lbi->lock); - - /* Now we can copy without holding the lock */ -@@ -5018,7 +5017,7 @@ log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_t size1, cha - memcpy(insert_point + size1, msg2, size2); - - /* Decrement the copy refcount */ -- slapi_atomic_decr(&(lbi->refcount), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_decr_64(&(lbi->refcount), __ATOMIC_RELEASE); - - /* If we are asked to sync to disk immediately, do so */ - if (!slapdFrontendConfig->accesslogbuffering) { -@@ -5038,7 +5037,7 @@ log_flush_buffer(LogBufferInfo *lbi, int type, int sync_now) - if (type == SLAPD_ACCESS_LOG) { - - /* It is only safe to flush once any other threads which are copying are finished */ -- while (slapi_atomic_load(&(lbi->refcount), __ATOMIC_ACQUIRE, ATOMIC_LONG) > 0) { -+ while (slapi_atomic_load_64(&(lbi->refcount), __ATOMIC_ACQUIRE) > 0) { - /* It's ok to sleep for a while because we only flush every second or so */ - DS_Sleep(PR_MillisecondsToInterval(1)); - } -diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c -index 6621ceb..8cc5318 100644 ---- a/ldap/servers/slapd/mapping_tree.c -+++ b/ldap/servers/slapd/mapping_tree.c -@@ -1647,7 +1647,7 @@ mapping_tree_init() - - /* we call this function from a single thread, so it should be ok */ - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown has been detected */ - return 0; - } -@@ -1759,8 +1759,6 @@ mtn_free_node(mapping_tree_node **node) - void - mapping_tree_free() - { -- int init_val = 1; -- - /* unregister dse callbacks */ - slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, MAPPING_TREE_BASE_DN, LDAP_SCOPE_BASE, "(objectclass=*)", mapping_tree_entry_modify_callback); - slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, MAPPING_TREE_BASE_DN, LDAP_SCOPE_BASE, "(objectclass=*)", mapping_tree_entry_add_callback); -@@ -1773,7 +1771,7 @@ mapping_tree_free() - slapi_unregister_backend_state_change_all(); - /* recursively free tree nodes */ - mtn_free_node(&mapping_tree_root); -- slapi_atomic_store(&mapping_tree_freed, &init_val, __ATOMIC_RELAXED, ATOMIC_INT); -+ slapi_atomic_store_32(&mapping_tree_freed, 1, __ATOMIC_RELAXED); - } - - /* This function returns the first node to parse when a search is done -@@ -2024,7 +2022,7 @@ slapi_dn_write_needs_referral(Slapi_DN *target_sdn, Slapi_Entry **referral) - mapping_tree_node *target_node = NULL; - int ret = 0; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - goto done; - } -@@ -2095,7 +2093,7 @@ slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry **re - int fixup = 0; - - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return LDAP_OPERATIONS_ERROR; - } -@@ -2200,7 +2198,7 @@ slapi_mapping_tree_select_all(Slapi_PBlock *pb, Slapi_Backend **be_list, Slapi_E - int flag_partial_result = 0; - int op_type; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - return LDAP_OPERATIONS_ERROR; - } - -@@ -2360,7 +2358,7 @@ slapi_mapping_tree_select_and_check(Slapi_PBlock *pb, char *newdn, Slapi_Backend - int ret; - int need_unlock = 0; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - return LDAP_OPERATIONS_ERROR; - } - -@@ -2526,7 +2524,7 @@ mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, Slapi_Backend **be, - int flag_stop = 0; - struct slapi_componentid *cid = NULL; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shut down detected */ - return LDAP_OPERATIONS_ERROR; - } -@@ -2714,7 +2712,7 @@ best_matching_child(mapping_tree_node *parent, - mapping_tree_node *highest_match_node = NULL; - mapping_tree_node *current; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -@@ -2741,7 +2739,7 @@ mtn_get_mapping_tree_node_by_entry(mapping_tree_node *node, const Slapi_DN *dn) - { - mapping_tree_node *found_node = NULL; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -@@ -2784,7 +2782,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 (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -@@ -2818,7 +2816,7 @@ get_mapping_tree_node_by_name(mapping_tree_node *node, char *be_name) - int i; - mapping_tree_node *found_node = NULL; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -@@ -2865,7 +2863,7 @@ slapi_get_mapping_tree_node_configdn(const Slapi_DN *root) - { - char *dn = NULL; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -@@ -2892,7 +2890,7 @@ slapi_get_mapping_tree_node_configsdn(const Slapi_DN *root) - char *dn = NULL; - Slapi_DN *sdn = NULL; - -- if (slapi_atomic_load(&mapping_tree_freed, __ATOMIC_RELAXED, ATOMIC_INT)) { -+ if (slapi_atomic_load_32(&mapping_tree_freed, __ATOMIC_RELAXED)) { - /* shutdown detected */ - return NULL; - } -diff --git a/ldap/servers/slapd/object.c b/ldap/servers/slapd/object.c -index 6a1a9a5..8e55a16 100644 ---- a/ldap/servers/slapd/object.c -+++ b/ldap/servers/slapd/object.c -@@ -43,12 +43,11 @@ Object * - object_new(void *user_data, FNFree destructor) - { - Object *o; -- uint64_t init_val = 1; - - o = (object *)slapi_ch_malloc(sizeof(object)); - o->destructor = destructor; - o->data = user_data; -- slapi_atomic_store(&(o->refcnt), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_store_64(&(o->refcnt), 1, __ATOMIC_RELEASE); - return o; - } - -@@ -62,7 +61,7 @@ void - object_acquire(Object *o) - { - PR_ASSERT(NULL != o); -- slapi_atomic_incr(&(o->refcnt), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(o->refcnt), __ATOMIC_RELEASE); - } - - -@@ -77,7 +76,7 @@ object_release(Object *o) - PRInt32 refcnt_after_release; - - PR_ASSERT(NULL != o); -- refcnt_after_release = slapi_atomic_decr(&(o->refcnt), __ATOMIC_ACQ_REL, ATOMIC_LONG); -+ refcnt_after_release = slapi_atomic_decr_64(&(o->refcnt), __ATOMIC_ACQ_REL); - if (refcnt_after_release == 0) { - /* Object can be destroyed */ - if (o->destructor) -diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c -index 70c530b..e0dd2bf 100644 ---- a/ldap/servers/slapd/psearch.c -+++ b/ldap/servers/slapd/psearch.c -@@ -134,7 +134,7 @@ ps_stop_psearch_system() - if (PS_IS_INITIALIZED()) { - PSL_LOCK_WRITE(); - for (ps = psearch_list->pl_head; NULL != ps; ps = ps->ps_next) { -- slapi_atomic_incr(&(ps->ps_complete), __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_incr_64(&(ps->ps_complete), __ATOMIC_RELEASE); - } - PSL_UNLOCK_WRITE(); - ps_wakeup_all(); -@@ -285,7 +285,7 @@ ps_send_results(void *arg) - - PR_Lock(psearch_list->pl_cvarlock); - -- while ((conn_acq_flag == 0) && slapi_atomic_load(&(ps->ps_complete), __ATOMIC_ACQUIRE, ATOMIC_LONG) == 0) { -+ while ((conn_acq_flag == 0) && slapi_atomic_load_64(&(ps->ps_complete), __ATOMIC_ACQUIRE) == 0) { - /* Check for an abandoned operation */ - if (pb_op == NULL || slapi_op_abandoned(ps->ps_pblock)) { - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", -@@ -427,7 +427,6 @@ static PSearch * - psearch_alloc(void) - { - PSearch *ps; -- uint64_t init_val = 0; - - ps = (PSearch *)slapi_ch_calloc(1, sizeof(PSearch)); - -@@ -438,7 +437,7 @@ psearch_alloc(void) - slapi_ch_free((void **)&ps); - return (NULL); - } -- slapi_atomic_store(&(ps->ps_complete), &init_val, __ATOMIC_RELEASE, ATOMIC_LONG); -+ slapi_atomic_store_64(&(ps->ps_complete), 0, __ATOMIC_RELEASE); - ps->ps_eq_head = ps->ps_eq_tail = (PSEQNode *)NULL; - ps->ps_lasttime = (time_t)0L; - ps->ps_next = NULL; -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index c434add..4566202 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -8202,56 +8202,87 @@ void slapi_operation_time_initiated(Slapi_Operation *o, struct timespec *initiat - */ - #endif - --/* See: https://gcc.gnu.org/ml/gcc/2016-11/txt6ZlA_JS27i.txt */ --#define ATOMIC_GENERIC 0 --#define ATOMIC_INT 4 --#define ATOMIC_LONG 8 --#define ATOMIC_INT128 16 /* Future */ -+/** -+ * Store a 32bit integral value atomicly -+ * -+ * \param ptr - integral pointer -+ * \param val - pointer to integral value (use integral type int32_t with ATOMIC_INT, or uint64_t -+ * with ATOMIC_LONG & ATOMIC_GENERIC) -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ */ -+void slapi_atomic_store_32(int32_t *ptr, int32_t val, int memorder); - - /** -- * Store an integral value atomicly -+ * Store a 64bit integral value atomicly - * - * \param ptr - integral pointer - * \param val - pointer to integral value (use integral type int32_t with ATOMIC_INT, or uint64_t - * with ATOMIC_LONG & ATOMIC_GENERIC) - * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, - * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -- * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG - */ --void slapi_atomic_store(void *ptr, void *val, int memorder, int type); -+void slapi_atomic_store_64(uint64_t *ptr, uint64_t val, int memorder); - - /** -- * Get an integral value atomicly -+ * Get a 32bit integral value atomicly - * - * \param ptr - integral pointer - * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, - * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -- * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG - * \return - - */ --uint64_t slapi_atomic_load(void *ptr, int memorder, int type); -+int32_t slapi_atomic_load_32(int32_t *ptr, int memorder); - - /** -- * Increment integral atomicly -+ * Get a 64bit integral value atomicly -+ * -+ * \param ptr - integral pointer -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \return ptr value -+ */ -+uint64_t slapi_atomic_load_64(uint64_t *ptr, int memorder); -+ -+/** -+ * Increment a 32bit integral atomicly - * - * \param ptr - pointer to integral to increment - * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, - * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -- * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG - * \return - new value of ptr - */ --uint64_t slapi_atomic_incr(void *ptr, int memorder, int type); -+int32_t slapi_atomic_incr_32(int32_t *ptr, int memorder); -+ -+/** -+ * Increment a 64bitintegral atomicly -+ * -+ * \param ptr - pointer to integral to increment -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \return - new value of ptr -+ */ -+uint64_t slapi_atomic_incr_64(uint64_t *ptr, int memorder); -+ -+/** -+ * Decrement a 32bit integral atomicly -+ * -+ * \param ptr - pointer to integral to decrement -+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, -+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -+ * \return - new value of ptr -+ */ -+int32_t slapi_atomic_decr_32(int32_t *ptr, int memorder); - - /** -- * Decrement integral atomicly -+ * Decrement a 64bitintegral atomicly - * - * \param ptr - pointer to integral to decrement - * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, - * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST -- * \param type - "ptr" type: ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG - * \return - new value of ptr - */ --uint64_t slapi_atomic_decr(void *ptr, int memorder, int type); -+uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder); - - - #ifdef __cplusplus -diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c -index 9e705b3..c5cae27 100644 ---- a/ldap/servers/slapd/slapi_counter.c -+++ b/ldap/servers/slapd/slapi_counter.c -@@ -295,53 +295,41 @@ slapi_counter_get_value(Slapi_Counter *counter) - * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, or __ATOMIC_SEQ_CST - * - * See: https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/_005f_005fatomic-Builtins.html -- * -- * type_size - ATOMIC_GENERIC, ATOMIC_INT, or ATOMIC_LONG, see slapi-plugin.h for more info -- * -- * Future: -- * If we need to support ATOMIC_INT128 (not available on 32bit systems): -- * __atomic_store_16((uint64_t *)&ptr, val, memorder); -- * __atomic_load_16((uint64_t *)&ptr, memorder); -- * __atomic_add_fetch_16((uint64_t *)&ptr, 1, memorder); -- * __atomic_sub_fetch_16((uint64_t *)&ptr, 1, memorder); - */ - - /* -- * "val" must be either int32_t or uint64_t -+ * atomic store functions (32bit and 64bit) - */ - void --slapi_atomic_store(void *ptr, void *val, int memorder, int type_size) -+slapi_atomic_store_32(int32_t *ptr, int32_t val, int memorder) - { - #ifdef ATOMIC_64BIT_OPERATIONS -- if (type_size == ATOMIC_INT) { -- __atomic_store_4((int32_t *)ptr, *(int32_t *)val, memorder); -- } else if (type_size == ATOMIC_LONG) { -- __atomic_store_8((uint64_t *)ptr, *(uint64_t *)val, memorder); -- } else { -- /* ATOMIC_GENERIC or unknown size */ -- __atomic_store((uint64_t *)&ptr, (uint64_t *)val, memorder); -- } -+ __atomic_store_4(ptr, val, memorder); - #else - PRInt32 *pr_ptr = (PRInt32 *)ptr; -- PR_AtomicSet(pr_ptr, *(PRInt32 *)val); -+ PR_AtomicSet(pr_ptr, (PRInt32)val); - #endif - } - --uint64_t --slapi_atomic_load(void *ptr, int memorder, int type_size) -+void -+slapi_atomic_store_64(uint64_t *ptr, uint64_t val, int memorder) - { - #ifdef ATOMIC_64BIT_OPERATIONS -- uint64_t ret; -+ __atomic_store_8(ptr, val, memorder); -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ PR_AtomicSet(pr_ptr, (PRInt32)val); -+#endif -+} - -- if (type_size == ATOMIC_INT) { -- return __atomic_load_4((int32_t *)ptr, memorder); -- } else if (type_size == ATOMIC_LONG) { -- return __atomic_load_8((uint64_t *)ptr, memorder); -- } else { -- /* ATOMIC_GENERIC or unknown size */ -- __atomic_load((uint64_t *)ptr, &ret, memorder); -- return ret; -- } -+/* -+ * atomic load functions (32bit and 64bit) -+ */ -+int32_t -+slapi_atomic_load_32(int32_t *ptr, int memorder) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ return __atomic_load_4(ptr, memorder); - #else - PRInt32 *pr_ptr = (PRInt32 *)ptr; - return PR_AtomicAdd(pr_ptr, 0); -@@ -349,17 +337,24 @@ slapi_atomic_load(void *ptr, int memorder, int type_size) - } - - uint64_t --slapi_atomic_incr(void *ptr, int memorder, int type_size) -+slapi_atomic_load_64(uint64_t *ptr, int memorder) - { - #ifdef ATOMIC_64BIT_OPERATIONS -- if (type_size == ATOMIC_INT) { -- return __atomic_add_fetch_4((int32_t *)ptr, 1, memorder); -- } else if (type_size == ATOMIC_LONG) { -- return __atomic_add_fetch_8((uint64_t *)ptr, 1, memorder); -- } else { -- /* ATOMIC_GENERIC or unknown size */ -- return __atomic_add_fetch((uint64_t *)ptr, 1, memorder); -- } -+ return __atomic_load_8(ptr, memorder); -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicAdd(pr_ptr, 0); -+#endif -+} -+ -+/* -+ * atomic increment functions (32bit and 64bit) -+ */ -+int32_t -+slapi_atomic_incr_32(int32_t *ptr, int memorder) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ return __atomic_add_fetch_4(ptr, 1, memorder); - #else - PRInt32 *pr_ptr = (PRInt32 *)ptr; - return PR_AtomicIncrement(pr_ptr); -@@ -367,17 +362,35 @@ slapi_atomic_incr(void *ptr, int memorder, int type_size) - } - - uint64_t --slapi_atomic_decr(void *ptr, int memorder, int type_size) -+slapi_atomic_incr_64(uint64_t *ptr, int memorder) - { - #ifdef ATOMIC_64BIT_OPERATIONS -- if (type_size == ATOMIC_INT) { -- return __atomic_sub_fetch_4((int32_t *)ptr, 1, memorder); -- } else if (type_size == ATOMIC_LONG) { -- return __atomic_sub_fetch_8((uint64_t *)ptr, 1, memorder); -- } else { -- /* ATOMIC_GENERIC or unknown size */ -- return __atomic_sub_fetch((uint64_t *)ptr, 1, memorder); -- } -+ return __atomic_add_fetch_8(ptr, 1, memorder); -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicIncrement(pr_ptr); -+#endif -+} -+ -+/* -+ * atomic decrement functions (32bit and 64bit) -+ */ -+int32_t -+slapi_atomic_decr_32(int32_t *ptr, int memorder) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ return __atomic_sub_fetch_4(ptr, 1, memorder); -+#else -+ PRInt32 *pr_ptr = (PRInt32 *)ptr; -+ return PR_AtomicDecrement(pr_ptr); -+#endif -+} -+ -+uint64_t -+slapi_atomic_decr_64(uint64_t *ptr, int memorder) -+{ -+#ifdef ATOMIC_64BIT_OPERATIONS -+ return __atomic_sub_fetch_8(ptr, 1, memorder); - #else - PRInt32 *pr_ptr = (PRInt32 *)ptr; - return PR_AtomicDecrement(pr_ptr); --- -2.9.5 - diff --git a/SOURCES/0002-Ticket-49165-pw_verify-did-not-handle-external-auth.patch b/SOURCES/0002-Ticket-49165-pw_verify-did-not-handle-external-auth.patch new file mode 100644 index 0000000..bbc9972 --- /dev/null +++ b/SOURCES/0002-Ticket-49165-pw_verify-did-not-handle-external-auth.patch @@ -0,0 +1,174 @@ +From 22f1ff8d87a7daf9fbbe2ddfbd195a6bfdae1cd6 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0002-Ticket-49385-Fix-coverity-warnings.patch b/SOURCES/0002-Ticket-49385-Fix-coverity-warnings.patch deleted file mode 100644 index 64e030f..0000000 --- a/SOURCES/0002-Ticket-49385-Fix-coverity-warnings.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 8308e20075adacfdf1827aaa3230e503207832bc Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 2 Oct 2017 09:33:29 -0400 -Subject: [PATCH] Ticket 49385 - Fix coverity warnings - -Description: This fixes coverity issues found from RHEL build of 1.3.7 - -https://pagure.io/389-ds-base/issue/49385 - -Reviewed by: lkrispenz(Thanks!) - -(cherry picked from commit 805e8f4d3016eb9c7906c1416482047a234d51ba) ---- - ldap/servers/plugins/http/http_impl.c | 1 + - ldap/servers/plugins/replication/urp.c | 10 ++++++---- - ldap/servers/plugins/syntaxes/string.c | 1 + - ldap/servers/slapd/back-ldbm/dbversion.c | 2 +- - ldap/servers/slapd/back-ldbm/index.c | 1 + - ldap/servers/slapd/conntable.c | 2 +- - ldap/servers/slapd/modify.c | 1 + - ldap/servers/slapd/plugin.c | 3 ++- - ldap/servers/slapd/referral.c | 18 +++++++++--------- - ldap/servers/slapd/task.c | 8 ++++++-- - ldap/servers/snmp/main.c | 13 +++++++++++-- - 11 files changed, 40 insertions(+), 20 deletions(-) - -diff --git a/ldap/servers/plugins/http/http_impl.c b/ldap/servers/plugins/http/http_impl.c -index d8bbe38..350c839 100644 ---- a/ldap/servers/plugins/http/http_impl.c -+++ b/ldap/servers/plugins/http/http_impl.c -@@ -601,6 +601,7 @@ sendPostReq(PRFileDesc *fd, const char *path, httpheader **httpheaderArray, char - if (path) { - path_len = strlen(path); - } else { -+ path = ""; - path_len = 0; - } - -diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c -index 3d63c64..9534c03 100644 ---- a/ldap/servers/plugins/replication/urp.c -+++ b/ldap/servers/plugins/replication/urp.c -@@ -856,7 +856,7 @@ urp_post_delete_operation(Slapi_PBlock *pb) - static int - urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - { -- Slapi_PBlock *add_pb = slapi_pblock_new(); -+ Slapi_PBlock *add_pb; - Slapi_Entry *cenotaph = NULL; - Slapi_Entry *pre_entry = NULL; - int ret = 0; -@@ -886,6 +886,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - slapi_rdn_remove_attr (rdn, SLAPI_ATTR_UNIQUEID ); - slapi_rdn_add(rdn, "cenotaphID", uniqueid); - newdn = slapi_ch_smprintf("%s,%s", slapi_rdn_get_rdn(rdn), parentdn); -+ slapi_rdn_free(&rdn); - slapi_ch_free_string(&parentdn); - /* slapi_sdn_free(&pre_sdn); */ - -@@ -902,6 +903,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - - slapi_log_err(SLAPI_LOG_REPL, sessionid, - "urp_fixup_add_cenotaph - addinng cenotaph: %s \n", newdn); -+ add_pb = slapi_pblock_new(); - slapi_pblock_init(add_pb); - - slapi_add_entry_internal_set_pb(add_pb, -@@ -1661,8 +1663,8 @@ urp_conflict_to_glue (char *sessionid, const Slapi_Entry *entry, Slapi_DN *paren - "urp_conflict_to_glue failed(%d) - %s --> %s\n", op_result, basedn, newrdn); - rc = 1; - } -- slapi_ch_free ( (void**)&newrdn ); - } -+ slapi_rdn_free(&parentrdn); - return rc; - } - /* -@@ -2166,11 +2168,11 @@ mod_objectclass_attr(const char *uniqueid, const Slapi_DN *entrysdn, const Slapi - { - Slapi_Mods smods; - int op_result; -- char csnstr[CSN_STRSIZE+1]; -+ char csnstr[CSN_STRSIZE+1] = {0}; - - slapi_mods_init(&smods, 3); - slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry"); -- slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", strlen(csnstr),csn_as_string(opcsn, PR_FALSE, csnstr)); -+ slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", CSN_STRSIZE, csn_as_string(opcsn, PR_FALSE, csnstr)); - op_result = urp_fixup_modify_entry(uniqueid, entrysdn, opcsn, &smods, 0); - slapi_mods_done(&smods); - if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) { -diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c -index f50dc13..e05ca7f 100644 ---- a/ldap/servers/plugins/syntaxes/string.c -+++ b/ldap/servers/plugins/syntaxes/string.c -@@ -391,6 +391,7 @@ bailout: - if (free_re) { - slapi_re_free(re); - } -+ slapi_ch_free_string(&alt); - slapi_ch_free((void **)&tmpbuf); /* NULL is fine */ - slapi_ch_free((void **)&bigpat); /* NULL is fine */ - -diff --git a/ldap/servers/slapd/back-ldbm/dbversion.c b/ldap/servers/slapd/back-ldbm/dbversion.c -index 01f86f4..5a77abd 100644 ---- a/ldap/servers/slapd/back-ldbm/dbversion.c -+++ b/ldap/servers/slapd/back-ldbm/dbversion.c -@@ -159,7 +159,7 @@ dbversion_read(struct ldbminfo *li, const char *directory, char **ldbmversion, c - } - (void)PR_Close(prfd); - -- if (*dataversion == NULL) { -+ if (dataversion == NULL || *dataversion == NULL) { - slapi_log_err(SLAPI_LOG_DEBUG, "dbversion_read", "dataversion not present in \"%s\"\n", filename); - } - if (*ldbmversion == NULL) { -diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c -index 798480e..58b11ed 100644 ---- a/ldap/servers/slapd/back-ldbm/index.c -+++ b/ldap/servers/slapd/back-ldbm/index.c -@@ -1063,6 +1063,7 @@ index_read_ext_allids( - /* The database might not exist. We have to assume it means empty set */ - slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "Failed to access idl index for %s\n", basetype); - slapi_log_err(SLAPI_LOG_TRACE, "index_read_ext_allids", "Assuming %s has no index values\n", basetype); -+ idl_free(&idl); - idl = idl_alloc(0); - break; - } else { -diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c -index c04ca0f..7c57b47 100644 ---- a/ldap/servers/slapd/conntable.c -+++ b/ldap/servers/slapd/conntable.c -@@ -347,7 +347,7 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e) - - PR_EnterMonitor(ct->c[i].c_mutex); - if (ct->c[i].c_sd != SLAPD_INVALID_SOCKET) { -- char buf2[20]; -+ char buf2[SLAPI_TIMESTAMP_BUFSIZE+1]; - size_t lendn = ct->c[i].c_dn ? strlen(ct->c[i].c_dn) : 6; /* "NULLDN" */ - size_t lenip = ct->c[i].c_ipaddr ? strlen(ct->c[i].c_ipaddr) : 0; - size_t lenconn = 1; -diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c -index 4b5a676..6309975 100644 ---- a/ldap/servers/slapd/modify.c -+++ b/ldap/servers/slapd/modify.c -@@ -923,6 +923,7 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw) - if (pw_encodevals_ext(pb, sdn, va)) { - slapi_log_err(SLAPI_LOG_CRIT, "op_shared_modify", "Unable to hash userPassword attribute for %s.\n", slapi_entry_get_dn_const(e)); - send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Unable to store attribute \"userPassword\" correctly\n", 0, NULL); -+ valuearray_free(&va); - goto free_and_return; - } - -diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c -index f47ff9b..e02133a 100644 ---- a/ldap/servers/slapd/plugin.c -+++ b/ldap/servers/slapd/plugin.c -@@ -4242,7 +4242,7 @@ bail: - int - slapi_set_plugin_default_config(const char *type, Slapi_Value *value) - { -- Slapi_PBlock *pb = slapi_pblock_new(); -+ Slapi_PBlock *pb; - Slapi_Entry **entries = NULL; - int rc = LDAP_SUCCESS; - char **search_attrs = NULL; /* used by search */ -@@ -4251,6 +4251,7 @@ slapi_set_plugin_default_config(const char *type, Slapi_Value *value) - return rc; - } - -+ pb = slapi_pblock_new(); - charray_add(&search_attrs, slapi_ch_strdup(type)); - - /* cn=plugin default config,cn=config */ -diff --git a/ldap/servers/slapd/referral.c b/ldap/servers/slapd/referral.c -index c5d9ffc..5935820 100644 ---- a/ldap/servers/slapd/referral.c -+++ b/ldap/servers/slapd/referral.c -@@ -153,7 +153,7 @@ referrals_free(void) - struct berval ** - ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int is_reference) - { -- int i, len, scope; -+ int i, len, scope = 0; - Slapi_DN *sdn = NULL; - char *p, *opdn_norm; - struct berval **urlscopy; -@@ -195,9 +195,9 @@ ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int i - - for (i = 0; urls[i] != NULL; ++i) { - /* -- * duplicate the URL, stripping off the label if there is one and -- * leaving extra room for "??base" in case we need to append that. -- */ -+ * duplicate the URL, stripping off the label if there is one and -+ * leaving extra room for "??base" in case we need to append that. -+ */ - urlscopy[i] = (struct berval *)slapi_ch_malloc( - sizeof(struct berval)); - if ((p = strchr(urls[i]->bv_val, ' ')) == NULL) { -@@ -210,16 +210,16 @@ ref_adjust(Slapi_PBlock *pb, struct berval **urls, const Slapi_DN *refsdn, int i - urlscopy[i]->bv_val[len] = '\0'; - - /* -- * adjust the baseDN as needed and set the length -- */ -+ * adjust the baseDN as needed and set the length -+ */ - adjust_referral_basedn(&urlscopy[i]->bv_val, refsdn, - opdn_norm, is_reference); - urlscopy[i]->bv_len = strlen(urlscopy[i]->bv_val); - - /* -- * if we are dealing with a continuation reference that resulted -- * from a one-level search, add a scope of base to the URL. -- */ -+ * if we are dealing with a continuation reference that resulted -+ * from a one-level search, add a scope of base to the URL. -+ */ - if (is_reference && operation_get_type(op) == SLAPI_OPERATION_SEARCH && - scope == LDAP_SCOPE_ONELEVEL) { - strcat(urlscopy[i]->bv_val, "??base"); -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index f3d02d9..53a0af5 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -278,6 +278,10 @@ slapi_task_log_notice(Slapi_Task *task, char *format, ...) - char buffer[LOG_BUFFER]; - size_t len; - -+ if (task == NULL) { -+ return; -+ } -+ - va_start(ap, format); - PR_vsnprintf(buffer, LOG_BUFFER, format, ap); - va_end(ap); -@@ -1089,11 +1093,11 @@ task_export_thread(void *arg) - slapi_pblock_get(pb, SLAPI_BACKEND_TASK, &task); - - g_incr_active_threadcnt(); -- for (count = 0, inp = instance_names; *inp; inp++, count++) -+ for (count = 0, inp = instance_names; inp && *inp; inp++, count++) - ; - slapi_task_begin(task, count); - -- for (inp = instance_names; *inp; inp++) { -+ for (inp = instance_names; inp && *inp; inp++) { - int release_me = 0; - /* lookup the backend */ - be = slapi_be_select_by_instance_name((const char *)*inp); -diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c -index 8477831..5bd318d 100644 ---- a/ldap/servers/snmp/main.c -+++ b/ldap/servers/snmp/main.c -@@ -21,6 +21,7 @@ - #include "ldap.h" - #include "ldif.h" - #include -+#include - - static char *agentx_master = NULL; - static char *agent_logdir = NULL; -@@ -54,9 +55,17 @@ main(int argc, char *argv[]) - { - char *s = getenv("DEBUG_SLEEP"); - if ((s != NULL) && isdigit(*s)) { -- int secs = atoi(s); -+ char *endp = NULL; -+ long secs; -+ errno = 0; -+ - printf("%s pid is %d\n", argv[0], getpid()); -- sleep(secs); -+ secs = strtol(s, &endp, 10); -+ if (*endp != '\0' || errno == ERANGE) { -+ sleep(10); -+ } else { -+ sleep(secs); -+ } - } - } - --- -2.9.5 - diff --git a/SOURCES/0003-Issue-49169-Fix-covscan-errors.patch b/SOURCES/0003-Issue-49169-Fix-covscan-errors.patch new file mode 100644 index 0000000..d989fed --- /dev/null +++ b/SOURCES/0003-Issue-49169-Fix-covscan-errors.patch @@ -0,0 +1,266 @@ +From 97f09918ef370c3be5aa64dcfeb3bb21e762f90d Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0003-Ticket-49180-errors-log-filled-with-attrlist_replace.patch b/SOURCES/0003-Ticket-49180-errors-log-filled-with-attrlist_replace.patch deleted file mode 100644 index 2be7aa7..0000000 --- a/SOURCES/0003-Ticket-49180-errors-log-filled-with-attrlist_replace.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 62fbb3423b26426e735e134134ab710945514ca6 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Tue, 26 Sep 2017 15:51:41 +0200 -Subject: [PATCH] Ticket: 49180 - errors log filled with attrlist_replace - - attr_replace - -Bug: If a RUV contains the same URL with different replica IDs the created referrals contain duplicates - -Fix: check duplicate referrals - -Reviewed by: Mark, thanks ---- - ldap/servers/plugins/replication/repl5_ruv.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c -index 40dc0928b..7bfdc3425 100644 ---- a/ldap/servers/plugins/replication/repl5_ruv.c -+++ b/ldap/servers/plugins/replication/repl5_ruv.c -@@ -1386,7 +1386,17 @@ ruv_replica_count(const RUV *ruv) - * Extract all the referral URL's from the RUV (but self URL), - * returning them in an array of strings, that - * the caller must free. -+ * We also check and remove duplicates (caused by unclean RUVs) - */ -+static int -+ruv_referral_exists(unsigned char *purl, char **refs, int count) -+{ -+ for (size_t j=0; jreplica_purl != NULL) && - (slapi_utf8casecmp((unsigned char *)replica->replica_purl, -- (unsigned char *)mypurl) != 0)) { -+ (unsigned char *)mypurl) != 0) && -+ !ruv_referral_exists((unsigned char *)replica->replica_purl, r, i)) { - r[i] = slapi_ch_strdup(replica->replica_purl); - i++; - } --- -2.13.6 - diff --git a/SOURCES/0004-Ticket-49171-Nunc-Stans-incorrectly-reports-a-timeou.patch b/SOURCES/0004-Ticket-49171-Nunc-Stans-incorrectly-reports-a-timeou.patch new file mode 100644 index 0000000..4f04068 --- /dev/null +++ b/SOURCES/0004-Ticket-49171-Nunc-Stans-incorrectly-reports-a-timeou.patch @@ -0,0 +1,96 @@ +From 645e628626f4a3d4b662c067584b4efc6b5c70c5 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0004-Ticket-49388-repl-monitor-matches-null-string-many-t.patch b/SOURCES/0004-Ticket-49388-repl-monitor-matches-null-string-many-t.patch deleted file mode 100644 index 2af9083..0000000 --- a/SOURCES/0004-Ticket-49388-repl-monitor-matches-null-string-many-t.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 80631ee86fa951f18ed25f61ca72734931eb5387 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 2 Oct 2017 16:19:47 -0400 -Subject: [PATCH] Ticket 49388 - repl-monitor - matches null string many times - in regex - -Bug Description: When using a wildcard(*) for the hostname, some of the - regex's for parsing the various configurations throws - out warnings. - -Fix Description: When a wildcard is detected reset the hostnode variable - to nothing. - -https://pagure.io/389-ds-base/issue/49388 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit 4b41a02484db645a593b9d6ac6c4e062dd374395) ---- - ldap/admin/src/scripts/repl-monitor.pl.in | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/ldap/admin/src/scripts/repl-monitor.pl.in b/ldap/admin/src/scripts/repl-monitor.pl.in -index a3efa8e6e..97c1462a5 100755 ---- a/ldap/admin/src/scripts/repl-monitor.pl.in -+++ b/ldap/admin/src/scripts/repl-monitor.pl.in -@@ -1053,6 +1053,10 @@ sub add_server - # Remove the domain name from the host name - my ($hostnode) = $host; - $hostnode = $1 if $host =~ /^(.+?)\./; -+ if ($hostnode eq "*") { -+ # handle wild card correctly for regex -+ $hostnode = ""; -+ } - - # new host:port - if (!$binddn || $binddn eq "" || $binddn eq "*" || --- -2.13.6 - diff --git a/SOURCES/0005-Issue-49169-Fix-covscan-errors-regression.patch b/SOURCES/0005-Issue-49169-Fix-covscan-errors-regression.patch new file mode 100644 index 0000000..757a4dc --- /dev/null +++ b/SOURCES/0005-Issue-49169-Fix-covscan-errors-regression.patch @@ -0,0 +1,36 @@ +From 6dde613c1a44731e017d262c2b5868dbe333da74 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0005-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch b/SOURCES/0005-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch deleted file mode 100644 index bdd9627..0000000 --- a/SOURCES/0005-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch +++ /dev/null @@ -1,257 +0,0 @@ -From bb2d74ebe9d725b47e35893a2d8c8bd713d6dd4b Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 3 Oct 2017 17:22:37 -0400 -Subject: [PATCH] Ticket 49389 - unable to retrieve specific cosAttribute when - subtree password policy is configured - -Bug Description: If indirect cos is being used and a subtree password - policy is added, th orignal COS attributes aren't always - returned. The issue is that when the subtree password - policy attribute was encountered during the virtual - attribute processing it set a flag that said the attribute - was operational (which is correct for the password policy - attr: pwdpolicysubentry). - - However, this flag was accidentally carried over to the - following virtual attributes that were being processed. - Which caused those attributes to be seen as operational - which is why it was no longer being returned to the client. - -Fix Description: Reset the prop flags before processing the next COS attribute - -https://pagure.io/389-ds-base/issue/49389 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit 0953e6011368bc29300990e9493ac13e5aba9586) ---- - dirsrvtests/tests/suites/cos/__init__.py | 0 - dirsrvtests/tests/suites/cos/indirect_cos_test.py | 191 ++++++++++++++++++++++ - ldap/servers/plugins/cos/cos_cache.c | 2 +- - 3 files changed, 192 insertions(+), 1 deletion(-) - create mode 100644 dirsrvtests/tests/suites/cos/__init__.py - create mode 100644 dirsrvtests/tests/suites/cos/indirect_cos_test.py - -diff --git a/dirsrvtests/tests/suites/cos/__init__.py b/dirsrvtests/tests/suites/cos/__init__.py -new file mode 100644 -index 000000000..e69de29bb -diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py -new file mode 100644 -index 000000000..1aac6b8ed ---- /dev/null -+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py -@@ -0,0 +1,191 @@ -+import logging -+import pytest -+import os -+import ldap -+import time -+import subprocess -+ -+from lib389 import Entry -+from lib389.idm.user import UserAccounts -+from lib389.topologies import topology_st as topo -+from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE, -+ SERVERID_STANDALONE, PORT_STANDALONE) -+ -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+TEST_USER_DN = "uid=test_user,ou=people,dc=example,dc=com" -+OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX) -+ -+PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,' \ -+ 'ou=people,dc=example,dc=com",' \ -+ 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com' -+ -+PW_POLICY_CONT_PEOPLE2 = 'cn="cn=nsPwPolicyEntry,' \ -+ 'dc=example,dc=com",' \ -+ 'cn=nsPwPolicyContainerdc=example,dc=com' -+ -+ -+def check_user(inst): -+ """Search the test user and make sure it has the execpted attrs -+ """ -+ try: -+ entries = inst.search_s('dc=example,dc=com', ldap.SCOPE_SUBTREE, "uid=test_user") -+ log.debug('user: \n' + str(entries[0])) -+ assert entries[0].hasAttr('ou'), "Entry is missing ou cos attribute" -+ assert entries[0].hasAttr('x-department'), "Entry is missing description cos attribute" -+ assert entries[0].hasAttr('x-en-ou'), "Entry is missing givenname cos attribute" -+ except ldap.LDAPError as e: -+ log.fatal('Failed to search for user: ' + str(e)) -+ raise e -+ -+ -+def setup_subtree_policy(topo): -+ """Set up subtree password policy -+ """ -+ try: -+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, -+ 'nsslapd-pwpolicy-local', -+ 'on')]) -+ except ldap.LDAPError as e: -+ log.error('Failed to set fine-grained policy: error {}'.format( -+ e.message['desc'])) -+ raise e -+ -+ log.info('Create password policy for subtree {}'.format(OU_PEOPLE)) -+ try: -+ subprocess.call(['%s/ns-newpwpolicy.pl' % topo.standalone.get_sbin_dir(), -+ '-D', DN_DM, '-w', PASSWORD, -+ '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE, -+ '-S', DEFAULT_SUFFIX, '-Z', SERVERID_STANDALONE]) -+ except subprocess.CalledProcessError as e: -+ log.error('Failed to create pw policy policy for {}: error {}'.format( -+ OU_PEOPLE, e.message['desc'])) -+ raise e -+ -+ log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE)) -+ try: -+ topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE, -+ 'pwdpolicysubentry', -+ PW_POLICY_CONT_PEOPLE2)]) -+ except ldap.LDAPError as e: -+ log.error('Failed to pwdpolicysubentry pw policy ' -+ 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc'])) -+ raise e -+ time.sleep(1) -+ -+ -+def setup_indirect_cos(topo): -+ """Setup indirect COS definition and template -+ """ -+ cosDef = Entry(('cn=cosDefinition,dc=example,dc=com', -+ {'objectclass': ['top', 'ldapsubentry', -+ 'cossuperdefinition', -+ 'cosIndirectDefinition'], -+ 'cosAttribute': ['ou merge-schemes', -+ 'x-department merge-schemes', -+ 'x-en-ou merge-schemes'], -+ 'cosIndirectSpecifier': 'seeAlso', -+ 'cn': 'cosDefinition'})) -+ -+ cosTemplate = Entry(('cn=cosTemplate,dc=example,dc=com', -+ {'objectclass': ['top', -+ 'extensibleObject', -+ 'cosTemplate'], -+ 'ou': 'My COS Org', -+ 'x-department': 'My COS x-department', -+ 'x-en-ou': 'my COS x-en-ou', -+ 'cn': 'cosTemplate'})) -+ try: -+ topo.standalone.add_s(cosDef) -+ topo.standalone.add_s(cosTemplate) -+ except ldap.LDAPError as e: -+ log.fatal('Failed to add cos: error ' + str(e)) -+ raise e -+ time.sleep(1) -+ -+ -+@pytest.fixture(scope="module") -+def setup(topo, request): -+ """Add schema, and test user -+ """ -+ log.info('Add custom schema...') -+ try: -+ ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " + -+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -+ ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " + -+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -+ OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " + -+ "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )") -+ topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1), -+ (ldap.MOD_ADD, 'attributeTypes', ATTR_2), -+ (ldap.MOD_ADD, 'objectClasses', OC)]) -+ except ldap.LDAPError as e: -+ log.fatal('Failed to add custom schema') -+ raise e -+ time.sleep(1) -+ -+ log.info('Add test user...') -+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) -+ -+ user_properties = { -+ 'uid': 'test_user', -+ 'cn': 'test user', -+ 'sn': 'user', -+ 'uidNumber': '1000', -+ 'gidNumber': '2000', -+ 'homeDirectory': '/home/test_user', -+ 'seeAlso': 'cn=cosTemplate,dc=example,dc=com' -+ } -+ users.create(properties=user_properties) -+ try: -+ topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD, -+ 'objectclass', -+ 'xPerson')]) -+ except ldap.LDAPError as e: -+ log.fatal('Failed to add objectclass to user') -+ raise e -+ -+ # Setup COS -+ log.info("Setup indirect COS...") -+ setup_indirect_cos(topo) -+ -+ -+def test_indirect_cos(topo, setup): -+ """Test indirect cos -+ -+ :id: 890d5929-7d52-4a56-956e-129611b4649a -+ :setup: standalone -+ :steps: -+ 1. Test cos is working for test user -+ 2. Add subtree password policy -+ 3. Test cos is working for test user -+ :expectedresults: -+ 1. User has expected cos attrs -+ 2. Substree password policy setup is successful -+ 3 User still has expected cos attrs -+ """ -+ -+ # Step 1 - Search user and see if the COS attrs are included -+ log.info('Checking user...') -+ check_user(topo.standalone) -+ -+ # Step 2 - Add subtree password policy (Second COS - operational attribute) -+ setup_subtree_policy(topo) -+ -+ # Step 3 - Check user again now hat we have a mix of vattrs -+ log.info('Checking user...') -+ check_user(topo.standalone) -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index c7897ba05..9ae15db15 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -2094,7 +2094,6 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)), - int index = 0; - cosCache *pCache; - char *lastattr = "thisisfakeforcos"; -- int props = 0; - - slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n"); - -@@ -2105,6 +2104,7 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)), - } - - while (index < pCache->attrCount) { -+ int props = 0; - if (slapi_utf8casecmp( - (unsigned char *)pCache->ppAttrIndex[index]->pAttrName, - (unsigned char *)lastattr)) { --- -2.13.6 - diff --git a/SOURCES/0006-Issue-49062-Reset-agmt-update-staus-and-total-init b/SOURCES/0006-Issue-49062-Reset-agmt-update-staus-and-total-init new file mode 100644 index 0000000..77c5104 --- /dev/null +++ b/SOURCES/0006-Issue-49062-Reset-agmt-update-staus-and-total-init @@ -0,0 +1,29 @@ +From 310b8f8b3c59423b9dfa3a6ea30f4a719f342fc9 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0006-Ticket-49320-Activating-already-active-role-returns-.patch b/SOURCES/0006-Ticket-49320-Activating-already-active-role-returns-.patch deleted file mode 100644 index c169905..0000000 --- a/SOURCES/0006-Ticket-49320-Activating-already-active-role-returns-.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 50d62b6d5ea69e5cad6359dbd1dccb09fcfa1a6b Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 3 Oct 2017 09:51:53 -0400 -Subject: [PATCH] Ticket 49320 - Activating already active role returns error - 16 - -Bug Description: ns-activate.pl returns error 16 when trying to activate an - already active role. - -Fix Description: Check for error 16 (no such attr), and return error 100. - Also added a "redirect"otion to the ldapmod function to - hide any errors printed to STDERR, so that the script can - display its own error message. - -https://pagure.io/389-ds-base/issue/49320 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit 406084847f29aa44ffd81de746770aeff6b67c61) ---- - ldap/admin/src/scripts/DSUtil.pm.in | 18 +++++++++++------- - ldap/admin/src/scripts/ns-activate.pl.in | 9 ++++++++- - 2 files changed, 19 insertions(+), 8 deletions(-) - -diff --git a/ldap/admin/src/scripts/DSUtil.pm.in b/ldap/admin/src/scripts/DSUtil.pm.in -index 805a9b91d..791464d0a 100644 ---- a/ldap/admin/src/scripts/DSUtil.pm.in -+++ b/ldap/admin/src/scripts/DSUtil.pm.in -@@ -1447,6 +1447,10 @@ sub ldapmod { - close (FILE); - } - -+ if ($info{redirect} eq ""){ -+ $info{redirect} = "> /dev/null"; -+ } -+ - # - # Check the protocol, and reset it if it's invalid - # -@@ -1470,9 +1474,9 @@ sub ldapmod { - print "STARTTLS)\n"; - } - if($info{openldap} eq "yes"){ -- system "ldapmodify -x -ZZ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -x -ZZ -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } else { -- system "ldapmodify -ZZZ -P \"$info{certdir}\" -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -ZZZ -P \"$info{certdir}\" -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } - } elsif (($info{security} eq "on" && $info{protocol} eq "") || ($info{security} eq "on" && $info{protocol} =~ m/LDAPS/i) ){ - # -@@ -1482,9 +1486,9 @@ sub ldapmod { - print "LDAPS)\n"; - } - if($info{openldap} eq "yes"){ -- system "ldapmodify -x -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -x -H \"ldaps://$info{host}:$info{secure_port}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } else { -- system "ldapmodify -Z -P \"$info{certdir}\" -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -Z -P \"$info{certdir}\" -p $info{secure_port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } - } elsif (($info{openldap} eq "yes") && (($info{ldapi} eq "on" && $info{protocol} eq "") || ($info{ldapi} eq "on" && $info{protocol} =~ m/LDAPI/i)) ){ - # -@@ -1499,7 +1503,7 @@ sub ldapmod { - if($protocol_error eq "yes"){ - print "LDAPI)\n"; - } -- system "ldapmodify -x -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -x -H \"$info{ldapiURL}\" -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } - } else { - # -@@ -1509,9 +1513,9 @@ sub ldapmod { - print "LDAP)\n"; - } - if($info{openldap} eq "yes"){ -- system "ldapmodify -x -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -x -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } else { -- system "ldapmodify -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" > /dev/null"; -+ system "ldapmodify -h $info{host} -p $info{port} -D \"$info{rootdn}\" -w $myrootdnpw $info{args} -f \"$file\" $info{redirect}"; - } - } - unlink ($file); -diff --git a/ldap/admin/src/scripts/ns-activate.pl.in b/ldap/admin/src/scripts/ns-activate.pl.in -index 5922c9aab..bec19c8e7 100644 ---- a/ldap/admin/src/scripts/ns-activate.pl.in -+++ b/ldap/admin/src/scripts/ns-activate.pl.in -@@ -731,11 +731,18 @@ if ( $single == 1 ){ - } - - $info{args} = "-c"; -+$info{redirect} = "> /dev/null 2>&1"; - DSUtil::ldapmod($record, %info); - if( $? != 0 ){ - debug("delete, $entry\n"); - $retCode=$?>>8; -- exit $retCode; -+ if ($retCode == "16") { # Error 16 (no such attr) - already activated -+ out("$entry already $state.\n"); -+ exit 100; -+ } else { -+ out("Failed to activate $entry, error $retCode\n"); -+ exit $retCode; -+ } - } - - out("$entry $state.\n"); --- -2.13.6 - diff --git a/SOURCES/0007-Issue-49065-dbmon.sh-fails-if-you-have-nsslapd-requi.patch b/SOURCES/0007-Issue-49065-dbmon.sh-fails-if-you-have-nsslapd-requi.patch new file mode 100644 index 0000000..b27dbb5 --- /dev/null +++ b/SOURCES/0007-Issue-49065-dbmon.sh-fails-if-you-have-nsslapd-requi.patch @@ -0,0 +1,174 @@ +From edf3d210e9ba9006f87e0597b052fa925c68ddc2 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0007-Ticket-48235-Remove-memberOf-global-lock.patch b/SOURCES/0007-Ticket-48235-Remove-memberOf-global-lock.patch deleted file mode 100644 index 42b3757..0000000 --- a/SOURCES/0007-Ticket-48235-Remove-memberOf-global-lock.patch +++ /dev/null @@ -1,914 +0,0 @@ -From cbe71d7e4901232eaa423b9dc55dba9401c05bec Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 13 Oct 2017 07:09:08 -0400 -Subject: [PATCH] Ticket 48235 - Remove memberOf global lock - -Bug Description: The memberOf global lock no longer servers a purpose since - the plugin is BETXN. This was causing potential deadlocks - when multiple backends are used. - -Fix Description: Remove the lock, and rework the fixup/ancestors caches/hashtables. - Instead of reusing a single cache, we create a fresh cache - when we copy the plugin config (which only happens at the start - of an operation). Then we destroy the caches when we free - the config. - -https://pagure.io/389-ds-base/issue/48235 - -Reviewed by: firstyear & tbordaz(Thanks!!) - -(cherry picked from commit 184b8a164f4ed456c72d58038aa9a0d512be61fa) ---- - ldap/servers/plugins/memberof/memberof.c | 326 +++--------------------- - ldap/servers/plugins/memberof/memberof.h | 17 ++ - ldap/servers/plugins/memberof/memberof_config.c | 166 +++++++++++- - 3 files changed, 210 insertions(+), 299 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index a0f997ddf..a23c52abe 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -48,14 +48,11 @@ static Slapi_PluginDesc pdesc = {"memberof", VENDOR, - static void *_PluginID = NULL; - static Slapi_DN *_ConfigAreaDN = NULL; - static Slapi_RWLock *config_rwlock = NULL; --static Slapi_DN *_pluginDN = NULL; --static PRMonitor *memberof_operation_lock = 0; -+static Slapi_DN* _pluginDN = NULL; - MemberOfConfig *qsortConfig = 0; - static int usetxn = 0; - static int premodfn = 0; --#define MEMBEROF_HASHTABLE_SIZE 1000 --static PLHashTable *fixup_entry_hashtable = NULL; /* global hash table protected by memberof_lock (memberof_operation_lock) */ --static PLHashTable *group_ancestors_hashtable = NULL; /* global hash table protected by memberof_lock (memberof_operation_lock) */ -+ - - typedef struct _memberofstringll - { -@@ -73,18 +70,6 @@ typedef struct _memberof_get_groups_data - PRBool use_cache; - } memberof_get_groups_data; - --/* The key to access the hash table is the normalized DN -- * The normalized DN is stored in the value because: -- * - It is used in slapi_valueset_find -- * - It is used to fill the memberof_get_groups_data.group_norm_vals -- */ --typedef struct _memberof_cached_value --{ -- char *key; -- char *group_dn_val; -- char *group_ndn_val; -- int valid; --} memberof_cached_value; - struct cache_stat - { - int total_lookup; -@@ -164,14 +149,9 @@ static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data); - static int memberof_entry_in_scope(MemberOfConfig *config, Slapi_DN *sdn); - static int memberof_add_objectclass(char *auto_add_oc, const char *dn); - static int memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc); --static PLHashTable *hashtable_new(); --static void fixup_hashtable_empty(char *msg); --static PLHashTable *hashtable_new(); --static void ancestor_hashtable_empty(char *msg); --static void ancestor_hashtable_entry_free(memberof_cached_value *entry); --static memberof_cached_value *ancestors_cache_lookup(const char *ndn); --static PRBool ancestors_cache_remove(const char *ndn); --static PLHashEntry *ancestors_cache_add(const void *key, void *value); -+static memberof_cached_value *ancestors_cache_lookup(MemberOfConfig *config, const char *ndn); -+static PRBool ancestors_cache_remove(MemberOfConfig *config, const char *ndn); -+static PLHashEntry *ancestors_cache_add(MemberOfConfig *config, const void *key, void *value); - - /*** implementation ***/ - -@@ -344,11 +324,6 @@ memberof_postop_start(Slapi_PBlock *pb) - slapi_log_err(SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, - "--> memberof_postop_start\n"); - -- memberof_operation_lock = PR_NewMonitor(); -- if (0 == memberof_operation_lock) { -- rc = -1; -- goto bail; -- } - if (config_rwlock == NULL) { - if ((config_rwlock = slapi_new_rwlock()) == NULL) { - rc = -1; -@@ -356,9 +331,6 @@ memberof_postop_start(Slapi_PBlock *pb) - } - } - -- fixup_entry_hashtable = hashtable_new(); -- group_ancestors_hashtable = hashtable_new(); -- - /* Set the alternate config area if one is defined. */ - slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area); - if (config_area) { -@@ -413,13 +385,13 @@ memberof_postop_start(Slapi_PBlock *pb) - goto bail; - } - --/* -+ /* - * TODO: start up operation actor thread - * need to get to a point where server failure -- * or shutdown doesn't hose our operations -- * so we should create a task entry that contains -+ * or shutdown doesn't hose our operations -+ * so we should create a task entry that contains - * all required information to complete the operation -- * then the tasks can be restarted safely if -+ * then the tasks can be restarted safely if - * interrupted - */ - -@@ -451,18 +423,7 @@ memberof_postop_close(Slapi_PBlock *pb __attribute__((unused))) - slapi_sdn_free(&_pluginDN); - slapi_destroy_rwlock(config_rwlock); - config_rwlock = NULL; -- PR_DestroyMonitor(memberof_operation_lock); -- memberof_operation_lock = NULL; -- -- if (fixup_entry_hashtable) { -- fixup_hashtable_empty("memberof_postop_close empty fixup_entry_hastable"); -- PL_HashTableDestroy(fixup_entry_hashtable); -- } - -- if (group_ancestors_hashtable) { -- ancestor_hashtable_empty("memberof_postop_close empty group_ancestors_hashtable"); -- PL_HashTableDestroy(group_ancestors_hashtable); -- } - slapi_log_err(SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM, - "<-- memberof_postop_close\n"); - return 0; -@@ -524,7 +485,7 @@ memberof_postop_del(Slapi_PBlock *pb) - { - int ret = SLAPI_PLUGIN_SUCCESS; - MemberOfConfig *mainConfig = NULL; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0}; - Slapi_DN *sdn; - void *caller_id = NULL; - -@@ -553,9 +514,6 @@ memberof_postop_del(Slapi_PBlock *pb) - memberof_copy_config(&configCopy, memberof_get_config()); - memberof_unlock_config(); - -- /* get the memberOf operation lock */ -- memberof_lock(); -- - /* remove this DN from the - * membership lists of groups - */ -@@ -563,7 +521,6 @@ memberof_postop_del(Slapi_PBlock *pb) - slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, - "memberof_postop_del - Error deleting dn (%s) from group. Error (%d)\n", - slapi_sdn_get_dn(sdn), ret); -- memberof_unlock(); - goto bail; - } - -@@ -583,7 +540,6 @@ memberof_postop_del(Slapi_PBlock *pb) - } - } - } -- memberof_unlock(); - bail: - memberof_free_config(&configCopy); - } -@@ -776,7 +732,7 @@ memberof_call_foreach_dn(Slapi_PBlock *pb __attribute__((unused)), Slapi_DN *sdn - memberof_cached_value *ht_grp = NULL; - const char *ndn = slapi_sdn_get_ndn(sdn); - -- ht_grp = ancestors_cache_lookup((const void *)ndn); -+ ht_grp = ancestors_cache_lookup(config, (const void *)ndn); - if (ht_grp) { - #if MEMBEROF_CACHE_DEBUG - slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_call_foreach_dn: Ancestors of %s already cached (%x)\n", ndn, ht_grp); -@@ -918,7 +874,7 @@ memberof_postop_modrdn(Slapi_PBlock *pb) - - if (memberof_oktodo(pb)) { - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0}; - struct slapi_entry *pre_e = NULL; - struct slapi_entry *post_e = NULL; - Slapi_DN *pre_sdn = 0; -@@ -944,8 +900,6 @@ memberof_postop_modrdn(Slapi_PBlock *pb) - goto bail; - } - -- memberof_lock(); -- - /* update any downstream members */ - if (pre_sdn && post_sdn && configCopy.group_filter && - 0 == slapi_filter_test_simple(post_e, configCopy.group_filter)) { -@@ -1010,7 +964,6 @@ memberof_postop_modrdn(Slapi_PBlock *pb) - } - } - } -- memberof_unlock(); - bail: - memberof_free_config(&configCopy); - } -@@ -1166,7 +1119,7 @@ memberof_postop_modify(Slapi_PBlock *pb) - if (memberof_oktodo(pb)) { - int config_copied = 0; - MemberOfConfig *mainConfig = 0; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0}; - - /* get the mod set */ - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); -@@ -1209,8 +1162,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - if (interested) { - int op = slapi_mod_get_operation(smod); - -- memberof_lock(); -- - /* the modify op decides the function */ - switch (op & ~LDAP_MOD_BVALUES) { - case LDAP_MOD_ADD: { -@@ -1221,7 +1172,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - "Error (%d)\n", - slapi_sdn_get_dn(sdn), ret); - slapi_mod_done(next_mod); -- memberof_unlock(); - goto bail; - } - break; -@@ -1239,7 +1189,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - "Error (%d)\n", - slapi_sdn_get_dn(sdn), ret); - slapi_mod_done(next_mod); -- memberof_unlock(); - goto bail; - } - } else { -@@ -1250,7 +1199,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - "Error (%d)\n", - slapi_sdn_get_dn(sdn), ret); - slapi_mod_done(next_mod); -- memberof_unlock(); - goto bail; - } - } -@@ -1265,7 +1213,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - "Error (%d)\n", - slapi_sdn_get_dn(sdn), ret); - slapi_mod_done(next_mod); -- memberof_unlock(); - goto bail; - } - break; -@@ -1280,8 +1227,6 @@ memberof_postop_modify(Slapi_PBlock *pb) - break; - } - } -- -- memberof_unlock(); - } - - slapi_mod_done(next_mod); -@@ -1336,7 +1281,7 @@ memberof_postop_add(Slapi_PBlock *pb) - - if (memberof_oktodo(pb) && (sdn = memberof_getsdn(pb))) { - struct slapi_entry *e = NULL; -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0}; - MemberOfConfig *mainConfig; - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e); - -@@ -1361,8 +1306,6 @@ memberof_postop_add(Slapi_PBlock *pb) - int i = 0; - Slapi_Attr *attr = 0; - -- memberof_lock(); -- - for (i = 0; configCopy.groupattrs && configCopy.groupattrs[i]; i++) { - if (0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr)) { - if ((ret = memberof_add_attr_list(pb, &configCopy, sdn, attr))) { -@@ -1373,8 +1316,6 @@ memberof_postop_add(Slapi_PBlock *pb) - } - } - } -- -- memberof_unlock(); - memberof_free_config(&configCopy); - } - } -@@ -2094,7 +2035,7 @@ dump_cache_entry(memberof_cached_value *double_check, const char *msg) - * the firsts elements of the array has 'valid=1' and the dn/ndn of group it belong to - */ - static void --cache_ancestors(Slapi_Value **member_ndn_val, memberof_get_groups_data *groups) -+cache_ancestors(MemberOfConfig *config, Slapi_Value **member_ndn_val, memberof_get_groups_data *groups) - { - Slapi_ValueSet *groupvals = *((memberof_get_groups_data *)groups)->groupvals; - Slapi_Value *sval; -@@ -2191,14 +2132,14 @@ cache_ancestors(Slapi_Value **member_ndn_val, memberof_get_groups_data *groups) - #if MEMBEROF_CACHE_DEBUG - dump_cache_entry(cache_entry, key); - #endif -- if (ancestors_cache_add((const void *)key_copy, (void *)cache_entry) == NULL) { -- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache_ancestors: Failed to cache ancestor of %s\n", key); -+ if (ancestors_cache_add(config, (const void*) key_copy, (void *) cache_entry) == NULL) { -+ slapi_log_err( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache_ancestors: Failed to cache ancestor of %s\n", key); - ancestor_hashtable_entry_free(cache_entry); -- slapi_ch_free((void **)&cache_entry); -+ slapi_ch_free ((void**)&cache_entry); - return; - } - #if MEMBEROF_CACHE_DEBUG -- if (double_check = ancestors_cache_lookup((const void *)key)) { -+ if (double_check = ancestors_cache_lookup(config, (const void*) key)) { - dump_cache_entry(double_check, "read back"); - } - #endif -@@ -2283,8 +2224,7 @@ memberof_get_groups_r(MemberOfConfig *config, Slapi_DN *member_sdn, memberof_get - - merge_ancestors(&member_ndn_val, &member_data, data); - if (!cached && member_data.use_cache) -- cache_ancestors(&member_ndn_val, &member_data); -- -+ cache_ancestors(config, &member_ndn_val, &member_data); - - slapi_value_free(&member_ndn_val); - slapi_valueset_free(groupvals); -@@ -2825,49 +2765,10 @@ memberof_qsort_compare(const void *a, const void *b) - val1, val2); - } - --/* betxn: This locking mechanism is necessary to guarantee the memberof -- * consistency */ --void --memberof_lock() --{ -- if (usetxn) { -- PR_EnterMonitor(memberof_operation_lock); -- } -- if (fixup_entry_hashtable) { -- fixup_hashtable_empty("memberof_lock"); -- } -- if (group_ancestors_hashtable) { -- ancestor_hashtable_empty("memberof_lock empty group_ancestors_hashtable"); -- memset(&cache_stat, 0, sizeof(cache_stat)); -- } --} -- --void --memberof_unlock() --{ -- if (group_ancestors_hashtable) { -- ancestor_hashtable_empty("memberof_unlock empty group_ancestors_hashtable"); --#if MEMBEROF_CACHE_DEBUG -- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache statistics: total lookup %d (success %d), add %d, remove %d, enum %d\n", -- cache_stat.total_lookup, cache_stat.successfull_lookup, -- cache_stat.total_add, cache_stat.total_remove, cache_stat.total_enumerate); -- slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "cache statistics duration: lookup %ld, add %ld, remove %ld, enum %ld\n", -- cache_stat.cumul_duration_lookup, cache_stat.cumul_duration_add, -- cache_stat.cumul_duration_remove, cache_stat.cumul_duration_enumerate); --#endif -- } -- if (fixup_entry_hashtable) { -- fixup_hashtable_empty("memberof_lock"); -- } -- if (usetxn) { -- PR_ExitMonitor(memberof_operation_lock); -- } --} -- - void - memberof_fixup_task_thread(void *arg) - { -- MemberOfConfig configCopy = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ MemberOfConfig configCopy = {0}; - Slapi_Task *task = (Slapi_Task *)arg; - task_data *td = NULL; - int rc = 0; -@@ -2933,9 +2834,6 @@ memberof_fixup_task_thread(void *arg) - /* do real work */ - rc = memberof_fix_memberof(&configCopy, task, td); - -- /* release the memberOf operation lock */ -- memberof_unlock(); -- - done: - if (usetxn && fixup_pb) { - if (rc) { /* failed */ -@@ -3100,7 +2998,7 @@ memberof_fix_memberof(MemberOfConfig *config, Slapi_Task *task, task_data *td) - } - - static memberof_cached_value * --ancestors_cache_lookup(const char *ndn) -+ancestors_cache_lookup(MemberOfConfig *config, const char *ndn) - { - memberof_cached_value *e; - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -@@ -3118,7 +3016,7 @@ ancestors_cache_lookup(const char *ndn) - } - #endif - -- e = (memberof_cached_value *)PL_HashTableLookupConst(group_ancestors_hashtable, (const void *)ndn); -+ e = (memberof_cached_value *) PL_HashTableLookupConst(config->ancestors_cache, (const void *) ndn); - - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) - if (start) { -@@ -3133,7 +3031,7 @@ ancestors_cache_lookup(const char *ndn) - return e; - } - static PRBool --ancestors_cache_remove(const char *ndn) -+ancestors_cache_remove(MemberOfConfig *config, const char *ndn) - { - PRBool rc; - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -@@ -3151,7 +3049,8 @@ ancestors_cache_remove(const char *ndn) - } - #endif - -- rc = PL_HashTableRemove(group_ancestors_hashtable, (const void *)ndn); -+ -+ rc = PL_HashTableRemove(config->ancestors_cache, (const void *)ndn); - - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) - if (start) { -@@ -3164,7 +3063,7 @@ ancestors_cache_remove(const char *ndn) - } - - static PLHashEntry * --ancestors_cache_add(const void *key, void *value) -+ancestors_cache_add(MemberOfConfig *config, const void *key, void *value) - { - PLHashEntry *e; - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -@@ -3181,7 +3080,7 @@ ancestors_cache_add(const void *key, void *value) - } - #endif - -- e = PL_HashTableAdd(group_ancestors_hashtable, key, value); -+ e = PL_HashTableAdd(config->ancestors_cache, key, value); - - #if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) - if (start) { -@@ -3211,7 +3110,6 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - const char *ndn; - char *dn_copy; - -- - /* - * If the server is ordered to shutdown, stop the fixup and return an error. - */ -@@ -3222,7 +3120,7 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - - /* Check if the entry has not already been fixed */ - ndn = slapi_sdn_get_ndn(sdn); -- if (ndn && fixup_entry_hashtable && PL_HashTableLookupConst(fixup_entry_hashtable, (void *)ndn)) { -+ if (ndn && config->fixup_cache && PL_HashTableLookupConst(config->fixup_cache, (void *)ndn)) { - slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: Entry %s already fixed up\n", ndn); - goto bail; - } -@@ -3240,12 +3138,13 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - * so free this memory - */ - ndn = slapi_sdn_get_ndn(sdn); -+ - #if MEMBEROF_CACHE_DEBUG - slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: This is NOT a group %s\n", ndn); - #endif -- ht_grp = ancestors_cache_lookup((const void *)ndn); -+ ht_grp = ancestors_cache_lookup(config, (const void *)ndn); - if (ht_grp) { -- if (ancestors_cache_remove((const void *)ndn)) { -+ if (ancestors_cache_remove(config, (const void *)ndn)) { - slapi_log_err(SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: free cached values for %s\n", ndn); - ancestor_hashtable_entry_free(ht_grp); - slapi_ch_free((void **)&ht_grp); -@@ -3297,11 +3196,11 @@ memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data) - slapi_valueset_free(groups); - - /* records that this entry has been fixed up */ -- if (fixup_entry_hashtable) { -+ if (config->fixup_cache) { - dn_copy = slapi_ch_strdup(ndn); -- if (PL_HashTableAdd(fixup_entry_hashtable, dn_copy, dn_copy) == NULL) { -+ if (PL_HashTableAdd(config->fixup_cache, dn_copy, dn_copy) == NULL) { - slapi_log_err(SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_fix_memberof_callback: " -- "failed to add dn (%s) in the fixup hashtable; NSPR error - %d\n", -+ "failed to add dn (%s) in the fixup hashtable; NSPR error - %d\n", - dn_copy, PR_GetError()); - slapi_ch_free((void **)&dn_copy); - /* let consider this as not a fatal error, it just skip an optimization */ -@@ -3397,157 +3296,8 @@ memberof_add_objectclass(char *auto_add_oc, const char *dn) - return rc; - } - --static PRIntn --memberof_hash_compare_keys(const void *v1, const void *v2) --{ -- PRIntn rc; -- if (0 == strcasecmp((const char *)v1, (const char *)v2)) { -- rc = 1; -- } else { -- rc = 0; -- } -- return rc; --} -- --static PRIntn --memberof_hash_compare_values(const void *v1, const void *v2) --{ -- PRIntn rc; -- if ((char *)v1 == (char *)v2) { -- rc = 1; -- } else { -- rc = 0; -- } -- return rc; --} -- --/* -- * Hashing function using Bernstein's method -- */ --static PLHashNumber --memberof_hash_fn(const void *key) --{ -- PLHashNumber hash = 5381; -- unsigned char *x = (unsigned char *)key; -- int c; -- -- while ((c = *x++)) { -- hash = ((hash << 5) + hash) ^ c; -- } -- return hash; --} -- --/* allocates the plugin hashtable -- * This hash table is used by operation and is protected from -- * concurrent operations with the memberof_lock (if not usetxn, memberof_lock -- * is not implemented and the hash table will be not used. -- * -- * The hash table contains all the DN of the entries for which the memberof -- * attribute has been computed/updated during the current operation -- * -- * hash table should be empty at the beginning and end of the plugin callback -- */ --static PLHashTable * --hashtable_new() --{ -- if (!usetxn) { -- return NULL; -- } -- -- return PL_NewHashTable(MEMBEROF_HASHTABLE_SIZE, -- memberof_hash_fn, -- memberof_hash_compare_keys, -- memberof_hash_compare_values, NULL, NULL); --} --/* this function called for each hash node during hash destruction */ --static PRIntn --fixup_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused))) --{ -- char *dn_copy; -- -- if (he == NULL) { -- return HT_ENUMERATE_NEXT; -- } -- dn_copy = (char *)he->value; -- slapi_ch_free_string(&dn_copy); -- -- return HT_ENUMERATE_REMOVE; --} -- --static void --fixup_hashtable_empty(char *msg) --{ -- if (fixup_entry_hashtable) { -- PL_HashTableEnumerateEntries(fixup_entry_hashtable, fixup_hashtable_remove, msg); -- } --} -- -- --/* allocates the plugin hashtable -- * This hash table is used by operation and is protected from -- * concurrent operations with the memberof_lock (if not usetxn, memberof_lock -- * is not implemented and the hash table will be not used. -- * -- * The hash table contains all the DN of the entries for which the memberof -- * attribute has been computed/updated during the current operation -- * -- * hash table should be empty at the beginning and end of the plugin callback -- */ -- --static void --ancestor_hashtable_entry_free(memberof_cached_value *entry) --{ -- int i; -- for (i = 0; entry[i].valid; i++) { -- slapi_ch_free((void **)&entry[i].group_dn_val); -- slapi_ch_free((void **)&entry[i].group_ndn_val); -- } -- /* Here we are at the ending element containing the key */ -- slapi_ch_free((void **)&entry[i].key); --} --/* this function called for each hash node during hash destruction */ --static PRIntn --ancestor_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused))) --{ -- memberof_cached_value *group_ancestor_array; -- -- if (he == NULL) { -- return HT_ENUMERATE_NEXT; -- } -- -- -- group_ancestor_array = (memberof_cached_value *)he->value; -- ancestor_hashtable_entry_free(group_ancestor_array); -- slapi_ch_free((void **)&group_ancestor_array); -- -- return HT_ENUMERATE_REMOVE; --} -- --static void --ancestor_hashtable_empty(char *msg) -+int -+memberof_use_txn() - { --#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -- long int start; -- struct timespec tsnow; --#endif -- -- if (group_ancestors_hashtable) { -- cache_stat.total_enumerate++; --#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -- if (clock_gettime(CLOCK_REALTIME, &tsnow) != 0) { -- start = 0; -- } else { -- start = tsnow.tv_nsec; -- } --#endif -- PL_HashTableEnumerateEntries(group_ancestors_hashtable, ancestor_hashtable_remove, msg); -- --#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) -- if (start) { -- if (clock_gettime(CLOCK_REALTIME, &tsnow) == 0) { -- cache_stat.cumul_duration_enumerate += (tsnow.tv_nsec - start); -- } -- } --#endif -- } -+ return usetxn; - } -diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h -index 4833ce221..ba64e9dfa 100644 ---- a/ldap/servers/plugins/memberof/memberof.h -+++ b/ldap/servers/plugins/memberof/memberof.h -@@ -64,8 +64,22 @@ typedef struct memberofconfig - int skip_nested; - int fixup_task; - char *auto_add_oc; -+ PLHashTable *ancestors_cache; -+ PLHashTable *fixup_cache; - } MemberOfConfig; - -+/* The key to access the hash table is the normalized DN -+ * The normalized DN is stored in the value because: -+ * - It is used in slapi_valueset_find -+ * - It is used to fill the memberof_get_groups_data.group_norm_vals -+ */ -+typedef struct _memberof_cached_value -+{ -+ char *key; -+ char *group_dn_val; -+ char *group_ndn_val; -+ int valid; -+} memberof_cached_value; - - /* - * functions -@@ -89,5 +103,8 @@ int memberof_apply_config(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entr - void *memberof_get_plugin_id(void); - void memberof_release_config(void); - PRUint64 get_plugin_started(void); -+void ancestor_hashtable_entry_free(memberof_cached_value *entry); -+PLHashTable *hashtable_new(); -+int memberof_use_txn(); - - #endif /* _MEMBEROF_H_ */ -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index c5ca4b137..3f22d95d6 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -14,12 +14,12 @@ - * memberof_config.c - configuration-related code for memberOf plug-in - * - */ -- -+#include "plhash.h" - #include -- - #include "memberof.h" - - #define MEMBEROF_CONFIG_FILTER "(objectclass=*)" -+#define MEMBEROF_HASHTABLE_SIZE 1000 - - /* - * The configuration attributes are contained in the plugin entry e.g. -@@ -34,14 +34,16 @@ - /* - * function prototypes - */ --static int memberof_validate_config(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e, int *returncode, char *returntext, void *arg); --static int --memberof_search(Slapi_PBlock *pb __attribute__((unused)), -- Slapi_Entry *entryBefore __attribute__((unused)), -- Slapi_Entry *e __attribute__((unused)), -- int *returncode __attribute__((unused)), -- char *returntext __attribute__((unused)), -- void *arg __attribute__((unused))) -+static void fixup_hashtable_empty( MemberOfConfig *config, char *msg); -+static void ancestor_hashtable_empty(MemberOfConfig *config, char *msg); -+static int memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, -+ int *returncode, char *returntext, void *arg); -+static int memberof_search (Slapi_PBlock *pb __attribute__((unused)), -+ Slapi_Entry* entryBefore __attribute__((unused)), -+ Slapi_Entry* e __attribute__((unused)), -+ int *returncode __attribute__((unused)), -+ char *returntext __attribute__((unused)), -+ void *arg __attribute__((unused))) - { - return SLAPI_DSE_CALLBACK_OK; - } -@@ -52,7 +54,7 @@ memberof_search(Slapi_PBlock *pb __attribute__((unused)), - /* This is the main configuration which is updated from dse.ldif. The - * config will be copied when it is used by the plug-in to prevent it - * being changed out from under a running memberOf operation. */ --static MemberOfConfig theConfig = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+static MemberOfConfig theConfig = {0}; - static Slapi_RWLock *memberof_config_lock = 0; - static int inited = 0; - -@@ -693,6 +695,13 @@ void - memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) - { - if (dest && src) { -+ -+ /* Allocate our caches here since we only copy the config at the start of an op */ -+ if (memberof_use_txn() == 1){ -+ dest->ancestors_cache = hashtable_new(); -+ dest->fixup_cache = hashtable_new(); -+ } -+ - /* Check if the copy is already up to date */ - if (src->groupattrs) { - int i = 0, j = 0; -@@ -787,6 +796,14 @@ memberof_free_config(MemberOfConfig *config) - slapi_ch_free_string(&config->memberof_attr); - memberof_free_scope(&(config->entryScopes), &config->entryScopeCount); - memberof_free_scope(&(config->entryScopeExcludeSubtrees), &config->entryExcludeScopeCount); -+ if (config->fixup_cache) { -+ fixup_hashtable_empty(config, "memberof_free_config empty fixup_entry_hastable"); -+ PL_HashTableDestroy(config->fixup_cache); -+ } -+ if (config->ancestors_cache) { -+ ancestor_hashtable_empty(config, "memberof_free_config empty group_ancestors_hashtable"); -+ PL_HashTableDestroy(config->ancestors_cache); -+ } - } - } - -@@ -982,3 +999,130 @@ bail: - - return ret; - } -+ -+ -+static PRIntn memberof_hash_compare_keys(const void *v1, const void *v2) -+{ -+ PRIntn rc; -+ if (0 == strcasecmp((const char *) v1, (const char *) v2)) { -+ rc = 1; -+ } else { -+ rc = 0; -+ } -+ return rc; -+} -+ -+static PRIntn memberof_hash_compare_values(const void *v1, const void *v2) -+{ -+ PRIntn rc; -+ if ((char *) v1 == (char *) v2) { -+ rc = 1; -+ } else { -+ rc = 0; -+ } -+ return rc; -+} -+ -+/* -+ * Hashing function using Bernstein's method -+ */ -+static PLHashNumber memberof_hash_fn(const void *key) -+{ -+ PLHashNumber hash = 5381; -+ unsigned char *x = (unsigned char *)key; -+ int c; -+ -+ while ((c = *x++)){ -+ hash = ((hash << 5) + hash) ^ c; -+ } -+ return hash; -+} -+ -+/* allocates the plugin hashtable -+ * This hash table is used by operation and is protected from -+ * concurrent operations with the memberof_lock (if not usetxn, memberof_lock -+ * is not implemented and the hash table will be not used. -+ * -+ * The hash table contains all the DN of the entries for which the memberof -+ * attribute has been computed/updated during the current operation -+ * -+ * hash table should be empty at the beginning and end of the plugin callback -+ */ -+PLHashTable *hashtable_new(int usetxn) -+{ -+ if (!usetxn) { -+ return NULL; -+ } -+ -+ return PL_NewHashTable(MEMBEROF_HASHTABLE_SIZE, -+ memberof_hash_fn, -+ memberof_hash_compare_keys, -+ memberof_hash_compare_values, NULL, NULL); -+} -+ -+/* this function called for each hash node during hash destruction */ -+static PRIntn fixup_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused))) -+{ -+ char *dn_copy; -+ -+ if (he == NULL) { -+ return HT_ENUMERATE_NEXT; -+ } -+ dn_copy = (char*) he->value; -+ slapi_ch_free_string(&dn_copy); -+ -+ return HT_ENUMERATE_REMOVE; -+} -+ -+static void fixup_hashtable_empty(MemberOfConfig *config, char *msg) -+{ -+ if (config->fixup_cache) { -+ PL_HashTableEnumerateEntries(config->fixup_cache, fixup_hashtable_remove, msg); -+ } -+} -+ -+ -+/* allocates the plugin hashtable -+ * This hash table is used by operation and is protected from -+ * concurrent operations with the memberof_lock (if not usetxn, memberof_lock -+ * is not implemented and the hash table will be not used. -+ * -+ * The hash table contains all the DN of the entries for which the memberof -+ * attribute has been computed/updated during the current operation -+ * -+ * hash table should be empty at the beginning and end of the plugin callback -+ */ -+ -+void ancestor_hashtable_entry_free(memberof_cached_value *entry) -+{ -+ int i; -+ -+ for (i = 0; entry[i].valid; i++) { -+ slapi_ch_free((void **) &entry[i].group_dn_val); -+ slapi_ch_free((void **) &entry[i].group_ndn_val); -+ } -+ /* Here we are at the ending element containing the key */ -+ slapi_ch_free((void**) &entry[i].key); -+} -+ -+/* this function called for each hash node during hash destruction */ -+static PRIntn ancestor_hashtable_remove(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused))) -+{ -+ memberof_cached_value *group_ancestor_array; -+ -+ if (he == NULL) { -+ return HT_ENUMERATE_NEXT; -+ } -+ group_ancestor_array = (memberof_cached_value *) he->value; -+ ancestor_hashtable_entry_free(group_ancestor_array); -+ slapi_ch_free((void **)&group_ancestor_array); -+ -+ return HT_ENUMERATE_REMOVE; -+} -+ -+static void ancestor_hashtable_empty(MemberOfConfig *config, char *msg) -+{ -+ if (config->ancestors_cache) { -+ PL_HashTableEnumerateEntries(config->ancestors_cache, ancestor_hashtable_remove, msg); -+ } -+} --- -2.13.6 - diff --git a/SOURCES/0008-Issue-49095-targetattr-wildcard-evaluation-is-incorr.patch b/SOURCES/0008-Issue-49095-targetattr-wildcard-evaluation-is-incorr.patch new file mode 100644 index 0000000..d3cbdb1 --- /dev/null +++ b/SOURCES/0008-Issue-49095-targetattr-wildcard-evaluation-is-incorr.patch @@ -0,0 +1,157 @@ +From abc9ff876209819c8f0dd7e799f1ab6a1b084fe5 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0008-Ticket-48235-remove-memberof-lock-cherry-pick-error.patch b/SOURCES/0008-Ticket-48235-remove-memberof-lock-cherry-pick-error.patch deleted file mode 100644 index 67d6c96..0000000 --- a/SOURCES/0008-Ticket-48235-remove-memberof-lock-cherry-pick-error.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 23a82820bce65653f96450fcc410706fa555fbfd Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 16 Oct 2017 10:44:29 -0400 -Subject: [PATCH] Ticket 48235 - remove memberof lock (cherry-pick error) - -Description: Fix cherry-pick error - -https://pagure.io/389-ds-base/issue/48235 - -Reviewed by: mreynolds(one line commit rule) - -(cherry picked from commit 3eb443b0ee11f3cf642ebfbcd135868a72ce39da) ---- - ldap/servers/plugins/memberof/memberof.c | 3 --- - ldap/servers/plugins/memberof/memberof.h | 2 -- - 2 files changed, 5 deletions(-) - -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index a23c52abe..bae242c81 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -2828,9 +2828,6 @@ memberof_fixup_task_thread(void *arg) - } - } - -- /* get the memberOf operation lock */ -- memberof_lock(); -- - /* do real work */ - rc = memberof_fix_memberof(&configCopy, task, td); - -diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h -index ba64e9dfa..cf028453c 100644 ---- a/ldap/servers/plugins/memberof/memberof.h -+++ b/ldap/servers/plugins/memberof/memberof.h -@@ -88,8 +88,6 @@ int memberof_config(Slapi_Entry *config_e, Slapi_PBlock *pb); - void memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src); - void memberof_free_config(MemberOfConfig *config); - MemberOfConfig *memberof_get_config(void); --void memberof_lock(void); --void memberof_unlock(void); - void memberof_rlock_config(void); - void memberof_wlock_config(void); - void memberof_unlock_config(void); --- -2.13.6 - diff --git a/SOURCES/0009-Issue-49157-ds-logpipe.py-crashes-for-non-existing-u.patch b/SOURCES/0009-Issue-49157-ds-logpipe.py-crashes-for-non-existing-u.patch new file mode 100644 index 0000000..a79e911 --- /dev/null +++ b/SOURCES/0009-Issue-49157-ds-logpipe.py-crashes-for-non-existing-u.patch @@ -0,0 +1,75 @@ +From e33f58d5a9984fd5d5533425fb420d05e6484d7f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0009-Ticket-49394-slapi_pblock_get-may-leave-unchanged-th.patch b/SOURCES/0009-Ticket-49394-slapi_pblock_get-may-leave-unchanged-th.patch deleted file mode 100644 index e2b42d7..0000000 --- a/SOURCES/0009-Ticket-49394-slapi_pblock_get-may-leave-unchanged-th.patch +++ /dev/null @@ -1,703 +0,0 @@ -From 0b58d1a62679c3961bc41e03591c4277fb9f183e Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Thu, 5 Oct 2017 12:50:50 +0200 -Subject: [PATCH] Ticket 49394 - slapi_pblock_get may leave unchanged the - provided variable - -Bug Description: - Since 1.3.6.4 the pblock struct is a split in sub-structs - (https://pagure.io/389-ds-base/issue/49097) - - Before, it was a quite flat calloc struct and any slapi-pblock-get - retrieved the field (NULL if not previously slapi_pblock_set) and - assigned the provided variable. - - Now, the sub-struct are allocated on demand (slapi_pblock_set). - If a substruct that contains the requested field is not allocated the - provided variable is unchanged. - - This is a change of behavior, because a uninitialized local variable can - get random value (stack) if the lookup field/struct has not been set. - -Fix Description: - Update slapi_pblock_set so that it systematically sets the - provided variable when those substructs are NULL - pb_mr - pb_dse - pb_task - pb_misc - pb_intop - pb_intplugin - pb_deprecated - -https://pagure.io/389-ds-base/issue/49394 - -Reviewed by: Mark Reynolds, William Brown - -Platforms tested: F23 - -Flag Day: no - -Doc impact: no ---- - ldap/servers/slapd/pblock.c | 166 +++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 165 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c -index 077684d23..8f87de5b5 100644 ---- a/ldap/servers/slapd/pblock.c -+++ b/ldap/servers/slapd/pblock.c -@@ -379,6 +379,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_BACKEND_COUNT: - if (pblock->pb_misc != NULL) { - (*(int *)value) = pblock->pb_misc->pb_backend_count; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_BE_TYPE: -@@ -616,6 +618,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_REQUESTOR_ISROOT: - if (pblock->pb_intop != NULL) { - (*(int *)value) = pblock->pb_intop->pb_requestor_isroot; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_SKIP_MODIFIED_ATTRS: -@@ -657,6 +661,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DESTROY_CONTENT: - if (pblock->pb_deprecated != NULL) { - (*(int *)value) = pblock->pb_deprecated->pb_destroy_content; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -685,16 +691,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_OPRETURN: - if (pblock->pb_intop != NULL) { - (*(int *)value) = pblock->pb_intop->pb_opreturn; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_PLUGIN_OBJECT: - if (pblock->pb_intplugin != NULL) { - (*(void **)value) = pblock->pb_intplugin->pb_object; -+ } else { -+ (*(void **)value) = NULL; - } - break; - case SLAPI_PLUGIN_DESTROY_FN: - if (pblock->pb_intplugin != NULL) { - (*(IFP *)value) = pblock->pb_intplugin->pb_destroy_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - case SLAPI_PLUGIN_DESCRIPTION: -@@ -703,11 +715,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_IDENTITY: - if (pblock->pb_intplugin != NULL) { - (*(void **)value) = pblock->pb_intplugin->pb_plugin_identity; -+ } else { -+ (*(void **)value) = NULL; - } - break; - case SLAPI_PLUGIN_CONFIG_AREA: - if (pblock->pb_intplugin != NULL) { - (*(char **)value) = pblock->pb_intplugin->pb_plugin_config_area; -+ } else { -+ (*(char **)value) = 0; - } - break; - case SLAPI_PLUGIN_CONFIG_DN: -@@ -718,16 +734,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_INTOP_RESULT: - if (pblock->pb_intop != NULL) { - (*(int *)value) = pblock->pb_intop->pb_internal_op_result; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry ***)value) = pblock->pb_intop->pb_plugin_internal_search_op_entries; -+ } else { -+ (*(Slapi_Entry ***)value) = NULL; - } - break; - case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS: - if (pblock->pb_intop != NULL) { - (*(char ***)value) = pblock->pb_intop->pb_plugin_internal_search_op_referrals; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - -@@ -1167,11 +1189,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_ENTRY_PRE_OP: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_pre_op_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_ENTRY_POST_OP: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_post_op_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - -@@ -1419,12 +1445,16 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_CONTROLS_ARG: /* used to pass control argument before operation is created */ - if (pblock->pb_intop != NULL) { - (*(LDAPControl ***)value) = pblock->pb_intop->pb_ctrls_arg; -+ } else { -+ (*(LDAPControl ***)value) = NULL; - } - break; - /* notes to be added to the access log RESULT line for this op. */ - case SLAPI_OPERATION_NOTES: - if (pblock->pb_intop != NULL) { - (*(unsigned int *)value) = pblock->pb_intop->pb_operation_notes; -+ } else { -+ (*(unsigned int *)value) = 0; - } - break; - -@@ -1486,6 +1516,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_SYNTAX_SUBSTRLENS: /* aka SLAPI_MR_SUBSTRLENS */ - if (pblock->pb_intplugin != NULL) { - (*(int **)value) = pblock->pb_intplugin->pb_substrlens; -+ } else { -+ (*(int **)value) = NULL; - } - break; - case SLAPI_PLUGIN_SYNTAX_VALIDATE: -@@ -1505,11 +1537,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_MANAGEDSAIT: - if (pblock->pb_intop != NULL) { - (*(int *)value) = pblock->pb_intop->pb_managedsait; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_PWPOLICY: - if (pblock->pb_intop != NULL) { - (*(int *)value) = pblock->pb_intop->pb_pwpolicy_ctrl; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -1522,11 +1558,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_ADD_EXISTING_DN_ENTRY: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_existing_dn_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_ADD_EXISTING_UNIQUEID_ENTRY: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_existing_uniqueid_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_ADD_PARENT_ENTRY: -@@ -1537,6 +1577,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_ADD_PARENT_UNIQUEID: - if (pblock->pb_op != NULL) { - (*(char **)value) = pblock->pb_op->o_params.p.p_add.parentuniqueid; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -1624,16 +1666,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_MODRDN_PARENT_ENTRY: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_parent_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_MODRDN_NEWPARENT_ENTRY: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_newparent_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_MODRDN_TARGET_ENTRY: - if (pblock->pb_intop != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_intop->pb_target_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_MODRDN_NEWSUPERIOR_ADDRESS: -@@ -1740,26 +1788,36 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_MR_FILTER_MATCH_FN: - if (pblock->pb_mr != NULL) { - (*(mrFilterMatchFn *)value) = pblock->pb_mr->filter_match_fn; -+ } else { -+ (*(mrFilterMatchFn *)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_FILTER_INDEX_FN: - if (pblock->pb_mr != NULL) { - (*(IFP *)value) = pblock->pb_mr->filter_index_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_FILTER_RESET_FN: - if (pblock->pb_mr != NULL) { - (*(IFP *)value) = pblock->pb_mr->filter_reset_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_INDEX_FN: - if (pblock->pb_mr != NULL) { - (*(IFP *)value) = pblock->pb_mr->index_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_INDEX_SV_FN: - if (pblock->pb_mr != NULL) { - (*(IFP *)value) = pblock->pb_mr->index_sv_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - -@@ -1767,41 +1825,57 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_MR_OID: - if (pblock->pb_mr != NULL) { - (*(char **)value) = pblock->pb_mr->oid; -+ } else { -+ (*(char **)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_TYPE: - if (pblock->pb_mr != NULL) { - (*(char **)value) = pblock->pb_mr->type; -+ } else { -+ (*(char **)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_VALUE: - if (pblock->pb_mr != NULL) { - (*(struct berval **)value) = pblock->pb_mr->value; -+ } else { -+ (*(struct berval **)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_VALUES: - if (pblock->pb_mr != NULL) { - (*(struct berval ***)value) = pblock->pb_mr->values; -+ } else { -+ (*(struct berval ***)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_KEYS: - if (pblock->pb_mr != NULL) { - (*(struct berval ***)value) = pblock->pb_mr->keys; -+ } else { -+ (*(struct berval ***)value) = NULL; - } - break; - case SLAPI_PLUGIN_MR_FILTER_REUSABLE: - if (pblock->pb_mr != NULL) { - (*(unsigned int *)value) = pblock->pb_mr->filter_reusable; -+ } else { -+ (*(unsigned int *)value) = 0; - } - break; - case SLAPI_PLUGIN_MR_QUERY_OPERATOR: - if (pblock->pb_mr != NULL) { - (*(int *)value) = pblock->pb_mr->query_operator; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_PLUGIN_MR_USAGE: - if (pblock->pb_mr != NULL) { - (*(unsigned int *)value) = pblock->pb_mr->usage; -+ } else { -+ (*(unsigned int *)value) = 0; - } - break; - -@@ -1865,16 +1939,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_SEQ_TYPE: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->seq_type; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_SEQ_ATTRNAME: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->seq_attrname; -+ } else { -+ (*(char **)value) = NULL; - } - break; - case SLAPI_SEQ_VAL: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->seq_val; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -1882,47 +1962,65 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_LDIF2DB_FILE: - if (pblock->pb_task != NULL) { - (*(char ***)value) = pblock->pb_task->ldif_files; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - case SLAPI_LDIF2DB_REMOVEDUPVALS: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->removedupvals; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_DB2INDEX_ATTRS: - if (pblock->pb_task != NULL) { - (*(char ***)value) = pblock->pb_task->db2index_attrs; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - case SLAPI_LDIF2DB_NOATTRINDEXES: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->ldif2db_noattrindexes; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_LDIF2DB_INCLUDE: - if (pblock->pb_task != NULL) { - (*(char ***)value) = pblock->pb_task->ldif_include; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - case SLAPI_LDIF2DB_EXCLUDE: - if (pblock->pb_task != NULL) { - (*(char ***)value) = pblock->pb_task->ldif_exclude; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - case SLAPI_LDIF2DB_GENERATE_UNIQUEID: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->ldif_generate_uniqueid; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_LDIF2DB_ENCRYPT: - case SLAPI_DB2LDIF_DECRYPT: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->ldif_encrypt; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_LDIF2DB_NAMESPACEID: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->ldif_namespaceid; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -1930,16 +2028,22 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DB2LDIF_PRINTKEY: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->ldif_printkey; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_DB2LDIF_DUMP_UNIQUEID: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->ldif_dump_uniqueid; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_DB2LDIF_FILE: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->ldif_file; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -1947,37 +2051,51 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_BACKEND_INSTANCE_NAME: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->instance_name; -+ } else { -+ (*(char **)value) = NULL; - } - break; - case SLAPI_BACKEND_TASK: - if (pblock->pb_task != NULL) { - (*(Slapi_Task **)value) = pblock->pb_task->task; -+ } else { -+ (*(Slapi_Task **)value) = NULL; - } - break; - case SLAPI_TASK_FLAGS: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->task_flags; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_DB2LDIF_SERVER_RUNNING: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->server_running; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_BULK_IMPORT_ENTRY: - if (pblock->pb_task != NULL) { - (*(Slapi_Entry **)value) = pblock->pb_task->import_entry; -+ } else { -+ (*(Slapi_Entry **)value) = NULL; - } - break; - case SLAPI_BULK_IMPORT_STATE: - if (pblock->pb_task != NULL) { - (*(int *)value) = pblock->pb_task->import_state; -+ } else { -+ (*(int *)value) = 0; - } - break; - /* dbverify */ - case SLAPI_DBVERIFY_DBDIR: - if (pblock->pb_task != NULL) { - (*(char **)value) = pblock->pb_task->dbverify_dbdir; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -1993,11 +2111,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_TXN: - if (pblock->pb_intop != NULL) { - (*(void **)value) = pblock->pb_intop->pb_txn; -+ } else { -+ (*(void **)value) = NULL; - } - break; - case SLAPI_TXN_RUV_MODS_FN: - if (pblock->pb_intop != NULL) { - (*(IFP *)value) = pblock->pb_intop->pb_txn_ruv_mods_fn; -+ } else { -+ (*(IFP *)value) = NULL; - } - break; - -@@ -2052,6 +2174,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PB_RESULT_TEXT: - if (pblock->pb_intop != NULL) { - *((char **)value) = pblock->pb_intop->pb_result_text; -+ } else { -+ *((char **)value) = NULL; - } - break; - -@@ -2059,6 +2183,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DBSIZE: - if (pblock->pb_misc != NULL) { - (*(unsigned int *)value) = pblock->pb_misc->pb_dbsize; -+ } else { -+ (*(unsigned int *)value) = 0; - } - break; - -@@ -2153,11 +2279,15 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_ARGC: - if (pblock->pb_misc != NULL) { - (*(int *)value) = pblock->pb_misc->pb_slapd_argc; -+ } else { -+ (*(int *)value) = 0; - } - break; - case SLAPI_ARGV: - if (pblock->pb_misc != NULL) { - (*(char ***)value) = pblock->pb_misc->pb_slapd_argv; -+ } else { -+ (*(char ***)value) = NULL; - } - break; - -@@ -2165,6 +2295,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_CONFIG_DIRECTORY: - if (pblock->pb_intplugin != NULL) { - (*(char **)value) = pblock->pb_intplugin->pb_slapd_configdir; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -2175,12 +2307,16 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_PWD_STORAGE_SCHEME_USER_PWD: - if (pblock->pb_deprecated != NULL) { - (*(char **)value) = pblock->pb_deprecated->pb_pwd_storage_scheme_user_passwd; -+ } else { -+ (*(char **)value) = NULL; - } - break; - - case SLAPI_PLUGIN_PWD_STORAGE_SCHEME_DB_PWD: - if (pblock->pb_deprecated != NULL) { - (*(char **)value) = pblock->pb_deprecated->pb_pwd_storage_scheme_db_passwd; -+ } else { -+ (*(char **)value) = NULL; - } - break; - -@@ -2208,6 +2344,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_PLUGIN_ENABLED: - if (pblock->pb_intplugin != NULL) { - *((int *)value) = pblock->pb_intplugin->pb_plugin_enabled; -+ } else { -+ *((int *)value) = 0; - } - break; - -@@ -2215,6 +2353,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DSE_DONT_WRITE_WHEN_ADDING: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->dont_add_write; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -2222,6 +2362,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DSE_MERGE_WHEN_ADDING: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->add_merge; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -2229,6 +2371,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DSE_DONT_CHECK_DUPS: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->dont_check_dups; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -2236,6 +2380,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DSE_REAPPLY_MODS: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->reapply_mods; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -2243,6 +2389,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_DSE_IS_PRIMARY_FILE: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->is_primary_file; -+ } else { -+ (*(int *)value) = 0; - } - break; - -@@ -2250,42 +2398,56 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_SCHEMA_FLAGS: - if (pblock->pb_dse != NULL) { - (*(int *)value) = pblock->pb_dse->schema_flags; -+ } else { -+ (*(int *)value) = 0; - } - break; - - case SLAPI_URP_NAMING_COLLISION_DN: - if (pblock->pb_intop != NULL) { - (*(char **)value) = pblock->pb_intop->pb_urp_naming_collision_dn; -+ } else { -+ (*(char **)value) = NULL; - } - break; - - case SLAPI_URP_TOMBSTONE_UNIQUEID: - if (pblock->pb_intop != NULL) { - (*(char **)value) = pblock->pb_intop->pb_urp_tombstone_uniqueid; -+ } else { -+ (*(char **)value) = NULL; - } - break; - - case SLAPI_URP_TOMBSTONE_CONFLICT_DN: - if (pblock->pb_intop != NULL) { -- (*(char **)value) = pblock->pb_intop->pb_urp_tombstone_conflict_dn; -+ (*(char **)value) = pblock->pb_intop->pb_urp_tombstone_conflict_dn; -+ } else { -+ (*(char **)value) = NULL; - } - break; - - case SLAPI_SEARCH_CTRLS: - if (pblock->pb_intop != NULL) { - (*(LDAPControl ***)value) = pblock->pb_intop->pb_search_ctrls; -+ } else { -+ (*(LDAPControl ***)value) = NULL; - } - break; - - case SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED: - if (pblock->pb_intplugin != NULL) { - (*(int *)value) = pblock->pb_intplugin->pb_syntax_filter_normalized; -+ } else { -+ (*(int *)value) = 0; - } - break; - - case SLAPI_PLUGIN_SYNTAX_FILTER_DATA: - if (pblock->pb_intplugin != NULL) { - (*(void **)value) = pblock->pb_intplugin->pb_syntax_filter_data; -+ } else { -+ (*(void **)value) = NULL; - } - break; - -@@ -2311,6 +2473,8 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - case SLAPI_ACI_TARGET_CHECK: - if (pblock->pb_misc != NULL) { - (*(int *)value) = pblock->pb_misc->pb_aci_target_check; -+ } else { -+ (*(int *)value) = 0; - } - break; - --- -2.13.6 - diff --git a/SOURCES/0010-Fix-double-free-in-_cl5NewDBFile-error-path.patch b/SOURCES/0010-Fix-double-free-in-_cl5NewDBFile-error-path.patch new file mode 100644 index 0000000..44813e8 --- /dev/null +++ b/SOURCES/0010-Fix-double-free-in-_cl5NewDBFile-error-path.patch @@ -0,0 +1,40 @@ +From 8c39c9dbe69949065940019e930c37b8f5450a75 Mon Sep 17 00:00:00 2001 +From: Adam Tkac +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 +--- + 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 + diff --git a/SOURCES/0010-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch b/SOURCES/0010-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch deleted file mode 100644 index de029d8..0000000 --- a/SOURCES/0010-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 697e01b0ca2d028f0d2cabc47ab2335de93b0491 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 16 Oct 2017 12:52:46 -0400 -Subject: [PATCH] Ticket 49402 - Adding a database entry with the same database - name that was deleted hangs server at shutdown - -Bug Description: At shutdown, after a backend was deleted, which also had a import - task run, the server hangs at shutdown. The issue is that the - import task destructor used the ldbm inst struct to see if it was - busy, but the inst was freed and the destructor was checking invalid - memory which caused a false positive on the "busy" check. - -Fix Description: Do not check if the instance is busy to tell if it's okay to remove - the task, instead just check the task's state. - -https://pagure.io/389-ds-base/issue/49402 - -Reviewed by: lkrispen(Thanks!) - -(cherry picked from commit bc6dbf15c160ac7e6c553133b2b936a981cfb7b6) ---- - ldap/servers/slapd/back-ldbm/import.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c -index e8f4a5615..42e2696d3 100644 ---- a/ldap/servers/slapd/back-ldbm/import.c -+++ b/ldap/servers/slapd/back-ldbm/import.c -@@ -244,7 +244,7 @@ import_task_destroy(Slapi_Task *task) - return; - } - -- while (is_instance_busy(job->inst)) { -+ while (task->task_state == SLAPI_TASK_RUNNING) { - /* wait for the job to finish before freeing it */ - DS_Sleep(PR_SecondsToInterval(1)); - } --- -2.13.6 - diff --git a/SOURCES/0011-Issue-49188-retrocl-can-crash-server-at-shutdown.patch b/SOURCES/0011-Issue-49188-retrocl-can-crash-server-at-shutdown.patch new file mode 100644 index 0000000..994fa70 --- /dev/null +++ b/SOURCES/0011-Issue-49188-retrocl-can-crash-server-at-shutdown.patch @@ -0,0 +1,34 @@ +From 8f908a1de1906a0b7451505d9640e2fd2f9fa7eb Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0011-Ticket-49064-RFE-allow-to-enable-MemberOf-plugin-in-.patch b/SOURCES/0011-Ticket-49064-RFE-allow-to-enable-MemberOf-plugin-in-.patch deleted file mode 100644 index 914e1d0..0000000 --- a/SOURCES/0011-Ticket-49064-RFE-allow-to-enable-MemberOf-plugin-in-.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 4af03a6a2a59684950d887d42c6e9d8b027d71f5 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Mon, 16 Oct 2017 11:21:51 +0200 -Subject: [PATCH] Ticket 49064 - RFE allow to enable MemberOf plugin in - dedicated consumer - -Bug Description: - memberof triggers some internal updates to add/del 'memberof' values. - on a readonly consumer, those updates selects a REFERRAL_ON_UPDATE backend - and that is not followed by internal updates. - At the end of the day, the update is rejected and if memberof plugin is enabled - replication will stuck on that rejected update - -Fix Description: - internal updates from memberof need to bypassing referrals. - So they flag internal updates SLAPI_OP_FLAG_BYPASS_REFERRALS, so that mtn_get_be - (mapping tree selection) will not return the referrals. - -https://pagure.io/389-ds-base/issue/49064 - -Reviewed by: Ludwig Krispenz, William Brown (thanks a LOT !) - -Platforms tested: F23 (all tickets + basic suite) - -Flag Day: no - -Doc impact: no ---- - dirsrvtests/tests/tickets/ticket49064_test.py | 259 ++++++++++++++++++++++++++ - ldap/servers/plugins/memberof/memberof.c | 6 +- - 2 files changed, 262 insertions(+), 3 deletions(-) - create mode 100644 dirsrvtests/tests/tickets/ticket49064_test.py - -diff --git a/dirsrvtests/tests/tickets/ticket49064_test.py b/dirsrvtests/tests/tickets/ticket49064_test.py -new file mode 100644 -index 000000000..b4b6de4b9 ---- /dev/null -+++ b/dirsrvtests/tests/tickets/ticket49064_test.py -@@ -0,0 +1,259 @@ -+import logging -+import pytest -+import os -+import time -+import ldap -+import subprocess -+from lib389.utils import ds_is_older -+from lib389.topologies import topology_m1h1c1 as topo -+from lib389._constants import * -+from lib389 import Entry -+ -+# Skip on older versions -+pytestmark = pytest.mark.skipif(ds_is_older('1.3.7'), reason="Not implemented") -+ -+USER_CN='user_' -+GROUP_CN='group_' -+FIXUP_FILTER = '(objectClass=*)' -+FIXUP_CMD = 'fixup-memberof.pl' -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+def memberof_fixup_task(server): -+ sbin_dir = server.get_sbin_dir() -+ memof_task = os.path.join(sbin_dir, FIXUP_CMD) -+ try: -+ output = subprocess.check_output( -+ [memof_task, '-D', DN_DM, '-w', PASSWORD, '-b', SUFFIX, '-Z', SERVERID_CONSUMER_1, '-f', FIXUP_FILTER]) -+ except subprocess.CalledProcessError as err: -+ output = err.output -+ log.info('output: {}'.format(output)) -+ expected = "Successfully added task entry" -+ assert expected in output -+ -+def config_memberof(server): -+ -+ server.plugins.enable(name=PLUGIN_MEMBER_OF) -+ MEMBEROF_PLUGIN_DN = ('cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config') -+ server.modify_s(MEMBEROF_PLUGIN_DN, [(ldap.MOD_REPLACE, -+ 'memberOfAllBackends', -+ 'on'), -+ (ldap.MOD_REPLACE, 'memberOfAutoAddOC', 'nsMemberOf')]) -+ # Configure fractional to prevent total init to send memberof -+ ents = server.agreement.list(suffix=DEFAULT_SUFFIX) -+ for ent in ents: -+ log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % ent.dn) -+ server.modify_s(ent.dn, -+ [(ldap.MOD_REPLACE, -+ 'nsDS5ReplicatedAttributeListTotal', -+ '(objectclass=*) $ EXCLUDE '), -+ (ldap.MOD_REPLACE, -+ 'nsDS5ReplicatedAttributeList', -+ '(objectclass=*) $ EXCLUDE memberOf')]) -+ -+ -+def send_updates_now(server): -+ -+ ents = server.agreement.list(suffix=DEFAULT_SUFFIX) -+ for ent in ents: -+ server.agreement.pause(ent.dn) -+ server.agreement.resume(ent.dn) -+ -+def add_user(server, no, desc='dummy', sleep=True): -+ cn = '%s%d' % (USER_CN, no) -+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX) -+ log.fatal('Adding user (%s): ' % dn) -+ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser'], -+ 'sn': ['_%s' % cn], -+ 'description': [desc]}))) -+ if sleep: -+ time.sleep(2) -+ -+def add_group(server, nr, sleep=True): -+ cn = '%s%d' % (GROUP_CN, nr) -+ dn = 'cn=%s,ou=groups,%s' % (cn, SUFFIX) -+ server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'], -+ 'description': 'group %d' % nr}))) -+ if sleep: -+ time.sleep(2) -+ -+def update_member(server, member_dn, group_dn, op, sleep=True): -+ mod = [(op, 'member', member_dn)] -+ server.modify_s(group_dn, mod) -+ if sleep: -+ time.sleep(2) -+ -+def _find_memberof(server, member_dn, group_dn, find_result=True): -+ ent = server.getEntry(member_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof']) -+ found = False -+ if ent.hasAttr('memberof'): -+ -+ for val in ent.getValues('memberof'): -+ server.log.info("!!!!!!! %s: memberof->%s" % (member_dn, val)) -+ server.log.info("!!!!!!! %s" % (val)) -+ server.log.info("!!!!!!! %s" % (group_dn)) -+ if val.lower() == group_dn.lower(): -+ found = True -+ break -+ -+ if find_result: -+ assert (found) -+ else: -+ assert (not found) -+ -+ -+def test_ticket49064(topo): -+ """Specify a test case purpose or name here -+ -+ :id: 60c11636-55a1-4704-9e09-2c6bcc828de4 -+ :setup: 1 Master - 1 Hub - 1 Consumer -+ :steps: -+ 1. Configure replication to EXCLUDE memberof -+ 2. Enable memberof plugin -+ 3. Create users/groups -+ 4. make user_1 member of group_1 -+ 5. Checks that user_1 is memberof group_1 on M,H,C -+ 6. make group_1 member of group_2 (nest group) -+ 7. Checks that user_1 is memberof group_1 and group_2 on M,H,C -+ 8. Check group_1 is memberof group_2 on M,H,C -+ 9. remove group_1 from group_2 -+ 10. Check group_1 and user_1 are NOT memberof group_2 on M,H,C -+ 11. remove user_1 from group_1 -+ 12. Check user_1 is NOT memberof group_1 and group_2 on M,H,C -+ 13. Disable memberof on C1 -+ 14. make user_1 member of group_1 -+ 15. Checks that user is memberof group_1 on M,H but not on C -+ 16. Enable memberof on C1 -+ 17. Checks that user is memberof group_1 on M,H but not on C -+ 18. Run memberof fixup task -+ 19. Checks that user is memberof group_1 on M,H,C -+ -+ -+ :expectedresults: -+ no assert for membership check -+ """ -+ -+ -+ M1 = topo.ms["master1"] -+ H1 = topo.hs["hub1"] -+ C1 = topo.cs["consumer1"] -+ -+ # Step 1 & 2 -+ M1.config.enable_log('audit') -+ config_memberof(M1) -+ M1.restart() -+ -+ H1.config.enable_log('audit') -+ config_memberof(H1) -+ H1.restart() -+ -+ C1.config.enable_log('audit') -+ config_memberof(C1) -+ C1.restart() -+ -+ # Step 3 -+ for i in range(10): -+ add_user(M1, i, desc='add on m1') -+ for i in range(3): -+ add_group(M1, i) -+ -+ # Step 4 -+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX) -+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX) -+ update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True) -+ -+ # Step 5 -+ for i in [M1, H1, C1]: -+ _find_memberof(i, member_dn, group_dn, find_result=True) -+ -+ -+ # Step 6 -+ user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX) -+ grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX) -+ grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX) -+ update_member(M1, grp1_dn, grp2_dn, ldap.MOD_ADD, sleep=True) -+ -+ # Step 7 -+ for i in [grp1_dn, grp2_dn]: -+ for inst in [M1, H1, C1]: -+ _find_memberof(inst, user_dn, i, find_result=True) -+ -+ # Step 8 -+ for i in [M1, H1, C1]: -+ _find_memberof(i, grp1_dn, grp2_dn, find_result=True) -+ -+ # Step 9 -+ user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX) -+ grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX) -+ grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX) -+ update_member(M1, grp1_dn, grp2_dn, ldap.MOD_DELETE, sleep=True) -+ -+ # Step 10 -+ for inst in [M1, H1, C1]: -+ for i in [grp1_dn, user_dn]: -+ _find_memberof(inst, i, grp2_dn, find_result=False) -+ -+ # Step 11 -+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX) -+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX) -+ update_member(M1, member_dn, group_dn, ldap.MOD_DELETE, sleep=True) -+ -+ # Step 12 -+ for inst in [M1, H1, C1]: -+ for grp in [grp1_dn, grp2_dn]: -+ _find_memberof(inst, member_dn, grp, find_result=False) -+ -+ # Step 13 -+ C1.plugins.disable(name=PLUGIN_MEMBER_OF) -+ C1.restart() -+ -+ # Step 14 -+ member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX) -+ group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX) -+ update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True) -+ -+ # Step 15 -+ for i in [M1, H1]: -+ _find_memberof(i, member_dn, group_dn, find_result=True) -+ _find_memberof(C1, member_dn, group_dn, find_result=False) -+ -+ # Step 16 -+ C1.plugins.enable(name=PLUGIN_MEMBER_OF) -+ C1.restart() -+ -+ # Step 17 -+ for i in [M1, H1]: -+ _find_memberof(i, member_dn, group_dn, find_result=True) -+ _find_memberof(C1, member_dn, group_dn, find_result=False) -+ -+ # Step 18 -+ memberof_fixup_task(C1) -+ time.sleep(5) -+ -+ # Step 19 -+ for i in [M1, H1, C1]: -+ _find_memberof(i, member_dn, group_dn, find_result=True) -+ -+ # If you need any test suite initialization, -+ # please, write additional fixture for that (including finalizer). -+ # Topology for suites are predefined in lib389/topologies.py. -+ -+ # If you need host, port or any other data about instance, -+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid) -+ -+ if DEBUGGING: -+ # Add debugging steps(if any)... -+ pass -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index bae242c81..44b52edbb 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -609,7 +609,7 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data) - slapi_modify_internal_set_pb_ext( - mod_pb, slapi_entry_get_sdn(e), - mods, 0, 0, -- memberof_get_plugin_id(), 0); -+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS); - - slapi_modify_internal_pb(mod_pb); - -@@ -3224,7 +3224,7 @@ memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc) - mod_pb = slapi_pblock_new(); - slapi_modify_internal_set_pb( - mod_pb, dn, mods, 0, 0, -- memberof_get_plugin_id(), 0); -+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS); - slapi_modify_internal_pb(mod_pb); - - slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); -@@ -3279,7 +3279,7 @@ memberof_add_objectclass(char *auto_add_oc, const char *dn) - - slapi_modify_internal_set_pb( - mod_pb, dn, mods, 0, 0, -- memberof_get_plugin_id(), 0); -+ memberof_get_plugin_id(), SLAPI_OP_FLAG_BYPASS_REFERRALS); - slapi_modify_internal_pb(mod_pb); - - slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); --- -2.13.6 - diff --git a/SOURCES/0012-Ticket-49177-rpm-would-not-create-valid-pkgconfig-fi.patch b/SOURCES/0012-Ticket-49177-rpm-would-not-create-valid-pkgconfig-fi.patch new file mode 100644 index 0000000..8b25c83 --- /dev/null +++ b/SOURCES/0012-Ticket-49177-rpm-would-not-create-valid-pkgconfig-fi.patch @@ -0,0 +1,131 @@ +From fffbb3d39a2ea12a2b3a72c729e76c1e69a19d8f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0012-Ticket-49378-server-init-fails.patch b/SOURCES/0012-Ticket-49378-server-init-fails.patch deleted file mode 100644 index 80c658b..0000000 --- a/SOURCES/0012-Ticket-49378-server-init-fails.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 82e092e9debce16f048b4fe0f38265bc8d80f63d Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Thu, 28 Sep 2017 09:11:00 +1000 -Subject: [PATCH] Ticket 49378 server init fails - -Bug Description: We used our own target for DS installation, but -we should just use multi-user like anything else. - -Fix Description: Change service template to multi-user. This should -be a seamless upgrade to most consumers. - -https://pagure.io/389-ds-base/issue/49378 - -Author: wibrown - -Review by: mreynolds (Thanks!) - -(cherry picked from commit e9ad5f5aca64f65fa2c9b2dc5132b0dacf131c99) ---- - wrappers/systemd.template.asan.service.in | 2 +- - wrappers/systemd.template.service.in | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/wrappers/systemd.template.asan.service.in b/wrappers/systemd.template.asan.service.in -index 1fe321ccb..52681f632 100644 ---- a/wrappers/systemd.template.asan.service.in -+++ b/wrappers/systemd.template.asan.service.in -@@ -36,5 +36,5 @@ ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/ - .include @initconfigdir@/@package_name@.systemd - - [Install] --WantedBy=dirsrv.target -+WantedBy=multi-user.target - -diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in -index 30b9e4b78..0d88900b6 100644 ---- a/wrappers/systemd.template.service.in -+++ b/wrappers/systemd.template.service.in -@@ -40,5 +40,5 @@ ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/ - .include @initconfigdir@/@package_name@.systemd - - [Install] --WantedBy=dirsrv.target -+WantedBy=multi-user.target - --- -2.13.6 - diff --git a/SOURCES/0013-Ticket-49076-To-debug-DB_DEADLOCK-condition-allow-to.patch b/SOURCES/0013-Ticket-49076-To-debug-DB_DEADLOCK-condition-allow-to.patch new file mode 100644 index 0000000..7d0d1c3 --- /dev/null +++ b/SOURCES/0013-Ticket-49076-To-debug-DB_DEADLOCK-condition-allow-to.patch @@ -0,0 +1,245 @@ +From 1a66f5f232d6c2869ef4e439eafe5a820f61a976 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0013-Ticket-49392-memavailable-not-available.patch b/SOURCES/0013-Ticket-49392-memavailable-not-available.patch deleted file mode 100644 index fabb740..0000000 --- a/SOURCES/0013-Ticket-49392-memavailable-not-available.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 9369164f45ba19519158286590aaefae1c64ef05 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Thu, 5 Oct 2017 09:54:48 +1000 -Subject: [PATCH] Ticket 49392 - memavailable not available - -Bug Description: On certain linux platforms memAvailable is -not actually available! This means that the value was 0, so -cgroup max was read instead, setting the system ram to: - -9223372036854771712 - -That's a bit excessive, and can cause memory allocations to fail. - -Fix Description: If memavail can't be found, fall back to -memtotal instead. - -https://pagure.io/389-ds-base/issue/49392 - -Author: wibrown - -Review by: mreynolds (Thanks!) ---- - ldap/servers/slapd/slapi_pal.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/slapi_pal.c b/ldap/servers/slapd/slapi_pal.c -index 38c178cfa..600d03d4d 100644 ---- a/ldap/servers/slapd/slapi_pal.c -+++ b/ldap/servers/slapd/slapi_pal.c -@@ -155,7 +155,16 @@ spal_meminfo_get() - - /* Both memtotal and memavail are in kb */ - memtotal = memtotal * 1024; -- memavail = memavail * 1024; -+ -+ /* -+ * Oracle Enterprise Linux doesn't provide a valid memavail value, so fall -+ * back to 80% of memtotal. -+ */ -+ if (memavail == 0) { -+ memavail = memtotal * 0.8; -+ } else { -+ memavail = memavail * 1024; -+ } - - /* If it's possible, get our cgroup info */ - uint64_t cg_mem_soft = 0; --- -2.13.6 - diff --git a/SOURCES/0014-Issue-49192-Deleting-suffix-can-hang-server.patch b/SOURCES/0014-Issue-49192-Deleting-suffix-can-hang-server.patch new file mode 100644 index 0000000..60a04d2 --- /dev/null +++ b/SOURCES/0014-Issue-49192-Deleting-suffix-can-hang-server.patch @@ -0,0 +1,244 @@ +From 353955ba9b4c487e30315d39d1880b6b784817d2 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0014-Ticket-48006-Missing-warning-for-invalid-replica-bac.patch b/SOURCES/0014-Ticket-48006-Missing-warning-for-invalid-replica-bac.patch deleted file mode 100644 index c7e308a..0000000 --- a/SOURCES/0014-Ticket-48006-Missing-warning-for-invalid-replica-bac.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 73c72aba0ab31f9d16cdfd8879e9da5f3fb985e0 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 17 Oct 2017 12:39:18 -0400 -Subject: [PATCH] Ticket 48006 - Missing warning for invalid replica backoff - configuration - -Description: Add warning if you try to set a min backoff time that is - greater than the configured maximum, or the max time that - is less than the minimum. - - Also fixed compiler warning in ldbm_config.c - -https://pagure.io/389-ds-base/issue/48006 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit e123acb6987c75f6d7282b32c4f279b976eb6f5e) ---- - .../plugins/replication/repl5_replica_config.c | 24 ++++++++++++++++++++-- - ldap/servers/slapd/back-ldbm/ldbm_config.c | 2 +- - 2 files changed, 23 insertions(+), 3 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index f28044c19..22d766143 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -465,7 +465,8 @@ replica_config_modify(Slapi_PBlock *pb, - } - } else if (strcasecmp(config_attr, type_replicaBackoffMin) == 0) { - if (apply_mods) { -- PRUint64 val = atoll(config_attr_value); -+ uint64_t val = atoll(config_attr_value); -+ uint64_t max; - - if (val <= 0) { - *returncode = LDAP_UNWILLING_TO_PERFORM; -@@ -475,11 +476,21 @@ replica_config_modify(Slapi_PBlock *pb, - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); - break; - } -+ max = replica_get_backoff_max(r); -+ if (val > max){ -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n", -+ config_attr, config_attr_value, (int)max); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ break; -+ } - replica_set_backoff_min(r, val); - } - } else if (strcasecmp(config_attr, type_replicaBackoffMax) == 0) { - if (apply_mods) { -- PRUint64 val = atoll(config_attr_value); -+ uint64_t val = atoll(config_attr_value); -+ uint64_t min; - - if (val <= 0) { - *returncode = LDAP_UNWILLING_TO_PERFORM; -@@ -490,6 +501,15 @@ replica_config_modify(Slapi_PBlock *pb, - errortext); - break; - } -+ min = replica_get_backoff_min(r); -+ if (val < min) { -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n", -+ config_attr, config_attr_value, (int)min); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ break; -+ } - replica_set_backoff_max(r, val); - } - } else if (strcasecmp(config_attr, type_replicaPrecisePurge) == 0) { -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c -index 2ef4652ce..feb993366 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_config.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c -@@ -388,7 +388,7 @@ ldbm_config_directory_set(void *arg, void *value, char *errorbuf, int phase, int - goto done; - } - slapi_pblock_destroy(search_pb); -- if (NULL == s || '\0' == s || 0 == PL_strcmp(s, "(null)")) { -+ if (NULL == s || '\0' == *s || 0 == PL_strcmp(s, "(null)")) { - slapi_log_err(SLAPI_LOG_ERR, - "ldbm_config_directory_set", "db directory is not set; check %s in the db config: %s\n", - CONFIG_DIRECTORY, CONFIG_LDBM_DN); --- -2.13.6 - diff --git a/SOURCES/0015-Ticket-49174-nunc-stans-can-not-use-negative-timeout.patch b/SOURCES/0015-Ticket-49174-nunc-stans-can-not-use-negative-timeout.patch new file mode 100644 index 0000000..f780980 --- /dev/null +++ b/SOURCES/0015-Ticket-49174-nunc-stans-can-not-use-negative-timeout.patch @@ -0,0 +1,200 @@ +From 4f90e73538f1faf101733fcd95392bb77ba9467c Mon Sep 17 00:00:00 2001 +From: William Brown +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 +--- + 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 + +- + 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 + diff --git a/SOURCES/0015-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch b/SOURCES/0015-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch deleted file mode 100644 index 26780eb..0000000 --- a/SOURCES/0015-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4569da8f2c55d54a34f31312ee5756c70a7f463c Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 19 Oct 2017 17:33:10 -0400 -Subject: [PATCH] Ticket 49408 - Server allows to set any nsds5replicaid in the - existing replica entry - -Description: There was no value validation for replica ID. Now there is. - -https://pagure.io/389-ds-base/issue/49408 - -Reviewed by: tbordaz(Thanks!) - -(cherry picked from commit 296f0abb78b7ec82580d039d9c505506f6ce07be) ---- - ldap/servers/plugins/replication/repl5_replica_config.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 22d766143..7477a292c 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -411,6 +411,18 @@ replica_config_modify(Slapi_PBlock *pb, - slapi_ch_free_string(&new_repl_type); - new_repl_type = slapi_ch_strdup(config_attr_value); - } else if (strcasecmp(config_attr, attr_replicaId) == 0) { -+ char *endp = NULL; -+ int64_t rid = 0; -+ errno = 0; -+ rid = strtoll(config_attr_value, &endp, 10); -+ if (*endp != '\0' || rid > 65535 || rid < 1 || errno == ERANGE) { -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number between 1 and 65535.\n", -+ config_attr, config_attr_value); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ break; -+ } - slapi_ch_free_string(&new_repl_id); - new_repl_id = slapi_ch_strdup(config_attr_value); - } else if (strcasecmp(config_attr, attr_flags) == 0) { --- -2.13.6 - diff --git a/SOURCES/0016-Issue-48989-Integer-overflow.patch b/SOURCES/0016-Issue-48989-Integer-overflow.patch new file mode 100644 index 0000000..484ad26 --- /dev/null +++ b/SOURCES/0016-Issue-48989-Integer-overflow.patch @@ -0,0 +1,1366 @@ +From be621fcd9f2215bba4c9190fd63815dc395814d8 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 28 Mar 2017 11:39:16 -0400 +Subject: [PATCH] Issue 48989 - Integer overflow + +Redo slapi_counters and monitors +--- + Makefile.am | 4 +- + configure.ac | 74 +++-- + ldap/servers/plugins/dna/dna.c | 20 +- + ldap/servers/plugins/posix-winsync/posix-winsync.c | 12 +- + ldap/servers/plugins/replication/repl5_init.c | 2 +- + ldap/servers/plugins/replication/repl_extop.c | 2 +- + ldap/servers/plugins/usn/usn.c | 16 +- + ldap/servers/slapd/back-ldbm/monitor.c | 4 +- + ldap/servers/slapd/back-ldbm/perfctrs.c | 12 +- + ldap/servers/slapd/back-ldbm/perfctrs.h | 74 ++--- + ldap/servers/slapd/back-ldbm/vlv_srch.h | 2 +- + ldap/servers/slapd/conntable.c | 14 +- + ldap/servers/slapd/entry.c | 4 +- + ldap/servers/slapd/log.c | 13 +- + ldap/servers/slapd/monitor.c | 14 +- + ldap/servers/slapd/slapi-plugin.h | 14 +- + ldap/servers/slapd/slapi_counter.c | 333 ++++----------------- + ldap/servers/slapd/slapi_counter_sunos_sparcv9.S | 105 ------- + ldap/servers/slapd/snmp_collator.c | 2 +- + test/libslapd/test.c | 2 + + test/test_slapd.h | 4 + + 21 files changed, 205 insertions(+), 522 deletions(-) + delete mode 100644 ldap/servers/slapd/slapi_counter_sunos_sparcv9.S + +diff --git a/Makefile.am b/Makefile.am +index df4a037..982dd28 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1222,9 +1222,6 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \ + $(libavl_a_SOURCES) + + libslapd_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(SASL_INCLUDES) @db_inc@ $(SVRCORE_INCLUDES) @kerberos_inc@ @pcre_inc@ +-if SPARC +-libslapd_la_SOURCES += ldap/servers/slapd/slapi_counter_sunos_sparcv9.S +-endif + libslapd_la_LIBADD = $(LDAPSDK_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(NSS_LINK) $(NSPR_LINK) $(KERBEROS_LINK) $(PCRE_LINK) $(THREADLIB) $(SYSTEMD_LINK) + libslapd_la_LDFLAGS = $(AM_LDFLAGS) $(SLAPD_LDFLAGS) + +@@ -2004,6 +2001,7 @@ TESTS = test_slapd \ + + test_slapd_SOURCES = test/main.c \ + test/libslapd/test.c \ ++ test/libslapd/counters/atomic.c \ + test/libslapd/pblock/analytics.c \ + test/libslapd/pblock/v3_compat.c \ + test/libslapd/operation/v3_compat.c +diff --git a/configure.ac b/configure.ac +index 3f2aa75..8172bab 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -555,7 +555,6 @@ case $host in + case $host in + i*86-*-linux*) + AC_DEFINE([CPU_x86], [], [cpu type x86]) +- AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter]) + ;; + x86_64-*-linux*) + with_xsixfour="yes" +@@ -565,23 +564,6 @@ case $host in + # wibrown -- 2017-02-21 disabled temporarily + # with_atomic_queue="yes" + # AC_DEFINE([ATOMIC_QUEUE_OPERATIONS], [1], [enabling atomic queue operations]) +- AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter]) +- +- AC_MSG_CHECKING([for SSE4.2 features ...]) +- save_CFLAGS="$CFLAGS" +- CFLAGS="$CFLAGS -msse4.2" +- AC_TRY_COMPILE( +- [], +- [return 0;], +- [ +- AC_DEFINE([HAVE_SSE4_2], [1], [Have sss4.2 on this platform arch]) +- AC_MSG_RESULT([SSE4.2 avaliable on this platform]) +- ], +- [ +- AC_MSG_RESULT([SSE4.2 not avaliable on this platform]) +- ] +- ) +- CFLAGS="$save_CFLAGS" + ;; + aarch64-*-linux*) + AC_DEFINE([CPU_arm], [], [cpu type arm]) +@@ -600,17 +582,6 @@ case $host in + s390x-*-linux*) + ;; + esac +- AC_MSG_CHECKING([for GCC provided 64-bit atomic bool cas function ...]) +- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], +- [[long long ptrval = 0, val = 0, newval = 1; (void)__sync_bool_compare_and_swap_8(&ptrval, val, newval);]])], +- [AC_DEFINE([HAVE_64BIT_ATOMIC_CAS_FUNC], [1], [have 64-bit atomic bool compare and swap function provided by gcc])AC_MSG_RESULT([yes])], +- [AC_MSG_RESULT([no])]) +- AC_MSG_CHECKING([for GCC provided 64-bit atomic ops functions ...]) +- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], +- [[long long ptrval = 0, val = 0; (void)__sync_add_and_fetch_8(&ptrval, val);]])], +- [AC_DEFINE([HAVE_64BIT_ATOMIC_OP_FUNCS], [1], [have 64-bit atomic operation functions provided by gcc])AC_MSG_RESULT([yes])], +- [AC_MSG_RESULT([no])]) +- + # some programs use the native thread library directly + THREADLIB=-lpthread + AC_SUBST([THREADLIB], [$THREADLIB]) +@@ -654,7 +625,6 @@ case $host in + AC_DEFINE([_POSIX_C_SOURCE], [199506L], [POSIX revision]) + AC_DEFINE([_HPUX_SOURCE], [1], [Source namespace]) + AC_DEFINE([_INCLUDE_STDC__SOURCE_199901], [1], [to pick up all of the printf format macros in inttypes.h]) +- AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter]) + # assume 64 bit + initconfigdir="/$PACKAGE_NAME/config" + perlexec='/opt/perl_64/bin/perl' +@@ -689,12 +659,11 @@ dnl Cstd and Crun are required to link any C++ related code + initdir='$(sysconfdir)/init.d' + case $host in + i?86-*-solaris2.1[[0-9]]*) +-dnl I dont know why i386 need this explicit ++ dnl I dont know why i386 need this explicit + AC_DEFINE([HAVE_GETPEERUCRED], [1], [have getpeerucred]) + ;; + sparc-*-solaris*) +-dnl includes some assembler stuff in counter.o +- AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter]) ++ dnl includes some assembler stuff in counter.o + AC_DEFINE([CPU_sparc], [], [cpu type sparc]) + TARGET='SPARC' + ;; +@@ -705,6 +674,45 @@ dnl includes some assembler stuff in counter.o + ;; + esac + ++AC_MSG_CHECKING([for SSE4.2 features ...]) ++save_CFLAGS="$CFLAGS" ++CFLAGS="$CFLAGS -msse4.2" ++AC_TRY_COMPILE( ++ [], ++ [return 0;], ++ [ ++ AC_DEFINE([HAVE_SSE4_2], [1], [Have sss4.2 on this platform arch]) ++ AC_MSG_RESULT([SSE4.2 avaliable on this platform]) ++ ], ++ [ ++ AC_MSG_RESULT([SSE4.2 not avaliable on this platform]) ++ ] ++) ++CFLAGS="$save_CFLAGS" ++ ++AC_MSG_CHECKING([for GCC provided 64-bit atomic operations]) ++AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ++ #include ++ ]], ++ [[ ++ uint64_t t_counter = 0; ++ uint64_t t_oldval = 0; ++ uint64_t t_newval = 1; ++ ++ __atomic_compare_exchange_8(&t_counter, &t_oldval, t_newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); ++ __atomic_add_fetch_8(&t_counter, t_newval, __ATOMIC_SEQ_CST); ++ __atomic_sub_fetch_8(&t_counter, t_newval, __ATOMIC_SEQ_CST); ++ __atomic_load(&t_counter, &t_oldval, __ATOMIC_SEQ_CST); ++ return 0; ++ ]])], ++ [ ++ AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [have 64-bit atomic operation functions provided by gcc]) ++ AC_MSG_RESULT([yes]) ++ ], ++ [ ++ AC_MSG_RESULT([no]) ++ ] ++) + + # cmd line overrides default setting above + if test -n "$with_initddir" ; then +diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c +index 54bbe86..34011b9 100644 +--- a/ldap/servers/plugins/dna/dna.c ++++ b/ldap/servers/plugins/dna/dna.c +@@ -2497,7 +2497,7 @@ static int dna_get_next_value(struct configEntry *config_entry, + if ((config_entry->maxval == -1) || + (nextval <= (config_entry->maxval + config_entry->interval))) { + /* try to set the new next value in the config entry */ +- PR_snprintf(next_value, sizeof(next_value),"%" NSPRIu64, nextval); ++ snprintf(next_value, sizeof(next_value),"%" NSPRIu64, nextval); + + /* set up our replace modify operation */ + replace_val[0] = next_value; +@@ -2565,13 +2565,13 @@ dna_get_shared_config_attr_val(struct configEntry *config_entry, char *attr, cha + if(slapi_sdn_compare(server->sdn, server_sdn) == 0){ + if(strcmp(attr, DNA_REMOTE_BIND_METHOD) == 0){ + if (server->remote_bind_method) { +- PR_snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_bind_method); ++ snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_bind_method); + found = 1; + } + break; + } else if(strcmp(attr, DNA_REMOTE_CONN_PROT) == 0){ + if (server->remote_conn_prot) { +- PR_snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_conn_prot); ++ snprintf(value, DNA_REMOTE_BUFSIZ, "%s", server->remote_conn_prot); + found = 1; + } + break; +@@ -2609,7 +2609,7 @@ dna_update_shared_config(struct configEntry *config_entry) + + /* We store the number of remaining assigned values + * in the shared config entry. */ +- PR_snprintf(remaining_vals, sizeof(remaining_vals),"%" NSPRIu64, ++ snprintf(remaining_vals, sizeof(remaining_vals),"%" NSPRIu64, + config_entry->remaining); + + /* set up our replace modify operation */ +@@ -2709,7 +2709,7 @@ dna_update_next_range(struct configEntry *config_entry, + int ret = 0; + + /* Try to set the new next range in the config entry. */ +- PR_snprintf(nextrange_value, sizeof(nextrange_value), "%" NSPRIu64 "-%" NSPRIu64, ++ snprintf(nextrange_value, sizeof(nextrange_value), "%" NSPRIu64 "-%" NSPRIu64, + lower, upper); + + /* set up our replace modify operation */ +@@ -2778,8 +2778,8 @@ dna_activate_next_range(struct configEntry *config_entry) + int ret = 0; + + /* Setup the modify operation for the config entry */ +- PR_snprintf(maxval_val, sizeof(maxval_val),"%" NSPRIu64, config_entry->next_range_upper); +- PR_snprintf(nextval_val, sizeof(nextval_val),"%" NSPRIu64, config_entry->next_range_lower); ++ snprintf(maxval_val, sizeof(maxval_val),"%" NSPRIu64, config_entry->next_range_upper); ++ snprintf(nextval_val, sizeof(nextval_val),"%" NSPRIu64, config_entry->next_range_lower); + + maxval_vals[0] = maxval_val; + maxval_vals[1] = 0; +@@ -4411,8 +4411,8 @@ static int dna_extend_exop(Slapi_PBlock *pb) + char highstr[16]; + + /* Create the exop response */ +- PR_snprintf(lowstr, sizeof(lowstr), "%" NSPRIu64, lower); +- PR_snprintf(highstr, sizeof(highstr), "%" NSPRIu64, upper); ++ snprintf(lowstr, sizeof(lowstr), "%" NSPRIu64, lower); ++ snprintf(highstr, sizeof(highstr), "%" NSPRIu64, upper); + range_low.bv_val = lowstr; + range_low.bv_len = strlen(range_low.bv_val); + range_high.bv_val = highstr; +@@ -4588,7 +4588,7 @@ dna_release_range(char *range_dn, PRUint64 *lower, PRUint64 *upper) + *lower = *upper - release + 1; + + /* try to set the new maxval in the config entry */ +- PR_snprintf(max_value, sizeof(max_value),"%" NSPRIu64, (*lower - 1)); ++ snprintf(max_value, sizeof(max_value),"%" NSPRIu64, (*lower - 1)); + + /* set up our replace modify operation */ + replace_val[0] = max_value; +diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c +index a7e024d..63444e5 100644 +--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c ++++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c +@@ -234,7 +234,7 @@ sync_acct_disable(void *cbdata, /* the usual domain config data */ + { + int ds_is_enabled = 1; /* default to true */ + int ad_is_enabled = 1; /* default to true */ +- unsigned long adval = 0; /* raw account val from ad entry */ ++ uint64_t adval = 0; /* raw account val from ad entry */ + int isvirt = 0; + + /* get the account lock state of the ds entry */ +@@ -270,9 +270,8 @@ sync_acct_disable(void *cbdata, /* the usual domain config data */ + if (update_entry) { + slapi_entry_attr_set_ulong(update_entry, "userAccountControl", adval); + slapi_log_err(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, +- "<-- sync_acct_disable - %s AD account [%s] - " +- "new value is [%ld]\n", (ds_is_enabled) ? "enabled" : "disabled", +- slapi_entry_get_dn_const(update_entry), adval); ++ "<-- sync_acct_disable - %s AD account [%s] - new value is [%" NSPRIu64 "]\n", ++ (ds_is_enabled) ? "enabled" : "disabled", slapi_entry_get_dn_const(update_entry), adval); + } else { + /* iterate through the mods - if there is already a mod + for userAccountControl, change it - otherwise, add it */ +@@ -327,9 +326,8 @@ sync_acct_disable(void *cbdata, /* the usual domain config data */ + mod_bval->bv_len = strlen(acctvalstr); + } + slapi_log_err(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, +- "<-- sync_acct_disable - %s AD account [%s] - " +- "new value is [%ld]\n", (ds_is_enabled) ? "enabled" : "disabled", +- slapi_entry_get_dn_const(ad_entry), adval); ++ "<-- sync_acct_disable - %s AD account [%s] - new value is [%" NSPRIu64 "]\n", ++ (ds_is_enabled) ? "enabled" : "disabled", slapi_entry_get_dn_const(ad_entry), adval); + } + } + +diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c +index 0945f7b..9549dcf 100644 +--- a/ldap/servers/plugins/replication/repl5_init.c ++++ b/ldap/servers/plugins/replication/repl5_init.c +@@ -208,7 +208,7 @@ get_repl_session_id (Slapi_PBlock *pb, char *idstr, CSN **csn) + /* Avoid "Connection is NULL and hence cannot access SLAPI_CONN_ID" */ + if (opid) { + slapi_pblock_get (pb, SLAPI_CONN_ID, &connid); +- PR_snprintf (idstr, REPL_SESSION_ID_SIZE, "conn=%" NSPRIu64 " op=%d", ++ snprintf (idstr, REPL_SESSION_ID_SIZE, "conn=%" NSPRIu64 " op=%d", + connid, opid); + } + +diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c +index 948f38d..80580f9 100644 +--- a/ldap/servers/plugins/replication/repl_extop.c ++++ b/ldap/servers/plugins/replication/repl_extop.c +@@ -865,7 +865,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + * the session's conn id and op id to identify the the supplier. + */ + /* junkrc = ruv_get_first_id_and_purl(supplier_ruv, &junkrid, &locking_purl); */ +- PR_snprintf(locking_session, sizeof(locking_session), "conn=%" NSPRIu64 " id=%d", ++ snprintf(locking_session, sizeof(locking_session), "conn=%" NSPRIu64 " id=%d", + connid, opid); + locking_purl = &locking_session[0]; + if (replica_get_exclusive_access(replica, &isInc, connid, opid, +diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c +index 6fe8d2e..5e67e0a 100644 +--- a/ldap/servers/plugins/usn/usn.c ++++ b/ldap/servers/plugins/usn/usn.c +@@ -360,7 +360,7 @@ _usn_mod_next_usn(LDAPMod ***mods, Slapi_Backend *be) + + /* add next USN to the mods; "be" contains the usn counter */ + usn_berval.bv_val = counter_buf; +- PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)); + usn_berval.bv_len = strlen(usn_berval.bv_val); + bvals[0] = &usn_berval; +@@ -670,7 +670,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* nsslapd-entryusn-global: on*/ + /* root dse shows ... + * lastusn: */ +- PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 1, "%s", USN_LAST_USN); ++ snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 1, "%s", USN_LAST_USN); + for (be = slapi_get_first_backend(&cookie); be; + be = slapi_get_next_backend(cookie)) { + if (be->be_usn_counter) { +@@ -681,10 +681,10 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* get a next USN counter from be_usn_counter; + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { +- PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { +- PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); + } + usn_berval.bv_len = strlen(usn_berval.bv_val); + slapi_entry_attr_replace(e, attr, vals); +@@ -693,7 +693,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* nsslapd-entryusn-global: off (default) */ + /* root dse shows ... + * lastusn;: */ +- PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 2, "%s;", USN_LAST_USN); ++ snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 2, "%s;", USN_LAST_USN); + attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN + 1; + for (be = slapi_get_first_backend(&cookie); be; + be = slapi_get_next_backend(cookie)) { +@@ -704,10 +704,10 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* get a next USN counter from be_usn_counter; + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { +- PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { +- PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); + } + usn_berval.bv_len = strlen(usn_berval.bv_val); + +@@ -716,7 +716,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + attr = (char *)slapi_ch_realloc(attr, attr_len); + attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN; + } +- PR_snprintf(attr_subp, attr_len - USN_LAST_USN_ATTR_CORE_LEN, ++ snprintf(attr_subp, attr_len - USN_LAST_USN_ATTR_CORE_LEN, + "%s", be->be_name); + slapi_entry_attr_replace(e, attr, vals); + } +diff --git a/ldap/servers/slapd/back-ldbm/monitor.c b/ldap/servers/slapd/back-ldbm/monitor.c +index dfcc735..757792b 100644 +--- a/ldap/servers/slapd/back-ldbm/monitor.c ++++ b/ldap/servers/slapd/back-ldbm/monitor.c +@@ -26,7 +26,7 @@ + + #define MSETF(_attr, _x) do { \ + char tmp_atype[37]; \ +- PR_snprintf(tmp_atype, sizeof(tmp_atype), _attr, _x); \ ++ snprintf(tmp_atype, sizeof(tmp_atype), _attr, _x); \ + MSET(tmp_atype); \ + } while (0) + +@@ -86,7 +86,7 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + MSET("entryCacheHits"); + sprintf(buf, "%lu", (long unsigned int)tries); + MSET("entryCacheTries"); +- sprintf(buf, "%lu", (unsigned long)(100.0*(double)hits / (double)(tries > 0 ? tries : 1))); ++ sprintf(buf, "%lu", (long unsigned int)(100.0*(double)hits / (double)(tries > 0 ? tries : 1))); + MSET("entryCacheHitRatio"); + sprintf(buf, "%lu", (long unsigned int)size); + MSET("currentEntryCacheSize"); +diff --git a/ldap/servers/slapd/back-ldbm/perfctrs.c b/ldap/servers/slapd/back-ldbm/perfctrs.c +index 2bd18bd..5929dea 100644 +--- a/ldap/servers/slapd/back-ldbm/perfctrs.c ++++ b/ldap/servers/slapd/back-ldbm/perfctrs.c +@@ -49,7 +49,7 @@ + + static void perfctrs_update(perfctrs_private *priv, DB_ENV *db_env); + static void perfctr_add_to_entry( Slapi_Entry *e, char *type, +- PRUint32 countervalue ); ++ uint64_t countervalue ); + + /* Init perf ctrs */ + void perfctrs_init(struct ldbminfo *li, perfctrs_private **ret_priv) +@@ -304,17 +304,13 @@ perfctrs_as_entry( Slapi_Entry *e, perfctrs_private *priv, DB_ENV *db_env ) + */ + for ( i = 0; i < SLAPI_LDBM_PERFCTR_AT_MAP_COUNT; ++i ) { + perfctr_add_to_entry( e, perfctr_at_map[i].pam_type, +- *((PRUint32 *)((char *)perf + perfctr_at_map[i].pam_offset))); ++ *((uint64_t *)((char *)perf + perfctr_at_map[i].pam_offset))); + } + } + + + static void +-perfctr_add_to_entry( Slapi_Entry *e, char *type, PRUint32 countervalue ) ++perfctr_add_to_entry( Slapi_Entry *e, char *type, uint64_t countervalue ) + { +- /* +- * XXXmcs: the following line assumes that long's are 32 bits or larger, +- * which we assume in other places too I am sure. +- */ +- slapi_entry_attr_set_ulong( e, type, (unsigned long)countervalue ); ++ slapi_entry_attr_set_ulong( e, type, countervalue ); + } +diff --git a/ldap/servers/slapd/back-ldbm/perfctrs.h b/ldap/servers/slapd/back-ldbm/perfctrs.h +index 65a7850..57be1d1 100644 +--- a/ldap/servers/slapd/back-ldbm/perfctrs.h ++++ b/ldap/servers/slapd/back-ldbm/perfctrs.h +@@ -11,46 +11,48 @@ + # include + #endif + ++#include ++ + /* Structure definition for performance data */ + /* This stuff goes in shared memory, so make sure the packing is consistent */ + + struct _performance_counters { +- PRUint32 sequence_number; +- PRUint32 lock_region_wait_rate; +- PRUint32 deadlock_rate; +- PRUint32 configured_locks; +- PRUint32 current_locks; +- PRUint32 max_locks; +- PRUint32 lockers; +- PRUint32 current_lock_objects; +- PRUint32 max_lock_objects; +- PRUint32 lock_conflicts; +- PRUint32 lock_request_rate; +- PRUint32 log_region_wait_rate; +- PRUint32 log_write_rate; +- PRUint32 log_bytes_since_checkpoint; +- PRUint32 cache_size_bytes; +- PRUint32 page_access_rate; +- PRUint32 cache_hit; +- PRUint32 cache_try; +- PRUint32 page_create_rate; +- PRUint32 page_read_rate; +- PRUint32 page_write_rate; +- PRUint32 page_ro_evict_rate; +- PRUint32 page_rw_evict_rate; +- PRUint32 hash_buckets; +- PRUint32 hash_search_rate; +- PRUint32 longest_chain_length; +- PRUint32 hash_elements_examine_rate; +- PRUint32 pages_in_use; +- PRUint32 dirty_pages; +- PRUint32 clean_pages; +- PRUint32 page_trickle_rate; +- PRUint32 cache_region_wait_rate; +- PRUint32 active_txns; +- PRUint32 commit_rate; +- PRUint32 abort_rate; +- PRUint32 txn_region_wait_rate; ++ uint64_t sequence_number; ++ uint64_t lock_region_wait_rate; ++ uint64_t deadlock_rate; ++ uint64_t configured_locks; ++ uint64_t current_locks; ++ uint64_t max_locks; ++ uint64_t lockers; ++ uint64_t current_lock_objects; ++ uint64_t max_lock_objects; ++ uint64_t lock_conflicts; ++ uint64_t lock_request_rate; ++ uint64_t log_region_wait_rate; ++ 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; ++ uint64_t page_read_rate; ++ uint64_t page_write_rate; ++ uint64_t page_ro_evict_rate; ++ uint64_t page_rw_evict_rate; ++ uint64_t hash_buckets; ++ uint64_t hash_search_rate; ++ uint64_t longest_chain_length; ++ uint64_t hash_elements_examine_rate; ++ uint64_t pages_in_use; ++ uint64_t dirty_pages; ++ uint64_t clean_pages; ++ uint64_t page_trickle_rate; ++ uint64_t cache_region_wait_rate; ++ uint64_t active_txns; ++ uint64_t commit_rate; ++ uint64_t abort_rate; ++ uint64_t txn_region_wait_rate; + }; + typedef struct _performance_counters performance_counters; + +diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.h b/ldap/servers/slapd/back-ldbm/vlv_srch.h +index d1eba08..6322f80 100644 +--- a/ldap/servers/slapd/back-ldbm/vlv_srch.h ++++ b/ldap/servers/slapd/back-ldbm/vlv_srch.h +@@ -92,7 +92,7 @@ struct vlvIndex + time_t vlv_lastchecked; + + /* The number of uses this search has received since start up */ +- PRUint32 vlv_uses; ++ uint64_t vlv_uses; + + struct backend* vlv_be; /* need backend to remove the index when done */ + +diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c +index 004aeae..bcafa4e 100644 +--- a/ldap/servers/slapd/conntable.c ++++ b/ldap/servers/slapd/conntable.c +@@ -395,7 +395,7 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e) + * 3 = The number of operations attempted that were blocked + * by max threads. + */ +- PR_snprintf(maxthreadbuf, sizeof(maxthreadbuf), "%d:%"NSPRIu64":%"NSPRIu64"", ++ snprintf(maxthreadbuf, sizeof(maxthreadbuf), "%d:%"NSPRIu64":%"NSPRIu64"", + maxthreadstate, ct->c[i].c_maxthreadscount, + ct->c[i].c_maxthreadsblocked); + +@@ -426,32 +426,32 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e) + PR_ExitMonitor(ct->c[i].c_mutex); + } + +- PR_snprintf( buf, sizeof(buf), "%d", nconns ); ++ snprintf( buf, sizeof(buf), "%d", nconns ); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "currentconnections", vals ); + +- PR_snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(num_conns)); ++ snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(num_conns)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "totalconnections", vals ); + +- PR_snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(conns_in_maxthreads)); ++ snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(conns_in_maxthreads)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "currentconnectionsatmaxthreads", vals ); + +- PR_snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(max_threads_count)); ++ snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(max_threads_count)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "maxthreadsperconnhits", vals ); + +- PR_snprintf( buf, sizeof(buf), "%d", (ct!=NULL?ct->size:0) ); ++ snprintf( buf, sizeof(buf), "%d", (ct!=NULL?ct->size:0) ); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "dtablesize", vals ); + +- PR_snprintf( buf, sizeof(buf), "%d", nreadwaiters ); ++ snprintf( buf, sizeof(buf), "%d", nreadwaiters ); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "readwaiters", vals ); +diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c +index 7bbd2f4..abacc57 100644 +--- a/ldap/servers/slapd/entry.c ++++ b/ldap/servers/slapd/entry.c +@@ -3088,14 +3088,14 @@ slapi_entry_attr_set_longlong( Slapi_Entry* e, const char *type, long long l) + } + + void +-slapi_entry_attr_set_ulong( Slapi_Entry* e, const char *type, unsigned long l) ++slapi_entry_attr_set_ulong( Slapi_Entry* e, const char *type, uint64_t l) + { + char value[16]; + struct berval bv; + struct berval *bvals[2]; + bvals[0] = &bv; + bvals[1] = NULL; +- sprintf(value,"%lu",l); ++ sprintf(value,"%" NSPRIu64, l); + bv.bv_val = value; + bv.bv_len = strlen( value ); + slapi_entry_attr_replace( e, type, bvals ); +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index 2f43a98..afedd5b 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -2327,11 +2327,11 @@ vslapd_log_error( + char buffer[SLAPI_LOG_BUFSIZ]; + char sev_name[10]; + int blen = TBUFSIZE; +- char *vbuf; ++ char *vbuf = NULL; + int header_len = 0; + int err = 0; + +- if ((vbuf = PR_vsmprintf(fmt, ap)) == NULL) { ++ if (vasprintf(&vbuf, fmt, ap) == -1) { + log__error_emergency("CRITICAL: vslapd_log_error, Unable to format message", 1 , locked); + return -1; + } +@@ -2381,10 +2381,10 @@ vslapd_log_error( + /* blen = strlen(buffer); */ + /* This truncates again .... But we have the nice smprintf above! */ + if (subsystem == NULL) { +- PR_snprintf (buffer+blen, sizeof(buffer)-blen, "- %s - %s", ++ snprintf (buffer+blen, sizeof(buffer)-blen, "- %s - %s", + get_log_sev_name(sev_level, sev_name), vbuf); + } else { +- PR_snprintf (buffer+blen, sizeof(buffer)-blen, "- %s - %s - %s", ++ snprintf (buffer+blen, sizeof(buffer)-blen, "- %s - %s - %s", + get_log_sev_name(sev_level, sev_name), subsystem, vbuf); + } + +@@ -2418,7 +2418,7 @@ vslapd_log_error( + g_set_shutdown( SLAPI_SHUTDOWN_EXIT ); + } + +- PR_smprintf_free (vbuf); ++ slapi_ch_free_string(&vbuf); + return( 0 ); + } + +@@ -2520,8 +2520,7 @@ static int vslapd_log_access(char *fmt, va_list ap) + time_t tnl; + + /* We do this sooner, because that we we can use the message in other calls */ +- vlen = PR_vsnprintf(vbuf, SLAPI_LOG_BUFSIZ, fmt, ap); +- if (! vlen) { ++ if ((vlen = vsnprintf(vbuf, SLAPI_LOG_BUFSIZ, fmt, ap)) == -1){ + log__error_emergency("CRITICAL: vslapd_log_access, Unable to format message", 1 ,0); + return -1; + } +diff --git a/ldap/servers/slapd/monitor.c b/ldap/servers/slapd/monitor.c +index 0917bc8..f1fb38f 100644 +--- a/ldap/servers/slapd/monitor.c ++++ b/ldap/servers/slapd/monitor.c +@@ -54,25 +54,25 @@ monitor_info(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *ret + attrlist_replace( &e->e_attrs, "version", vals ); + slapi_ch_free( (void **) &val.bv_val ); + +- val.bv_len = PR_snprintf( buf, sizeof(buf), "%d", g_get_active_threadcnt() ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%d", g_get_active_threadcnt() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "threads", vals ); + + connection_table_as_entry(the_connection_table, e); + +- val.bv_len = PR_snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_initiated) ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_initiated) ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "opsinitiated", vals ); + +- val.bv_len = PR_snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_completed) ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_completed) ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "opscompleted", vals ); + +- val.bv_len = PR_snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_entries_sent() ); ++ val.bv_len = snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_entries_sent() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "entriessent", vals ); + +- val.bv_len = PR_snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_bytes_sent() ); ++ val.bv_len = snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_bytes_sent() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "bytessent", vals ); + +@@ -88,12 +88,12 @@ monitor_info(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *ret + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "starttime", vals ); + +- val.bv_len = PR_snprintf( buf, sizeof(buf), "%d", be_nbackends_public() ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%d", be_nbackends_public() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "nbackends", vals ); + + #ifdef THREAD_SUNOS5_LWP +- val.bv_len = PR_snprintf( buf, sizeof(buf), "%d", thr_getconcurrency() ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%d", thr_getconcurrency() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "concurrency", vals ); + #endif +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 1bd8fc8..725fa1c 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -1954,7 +1954,7 @@ void slapi_entry_attr_set_longlong( Slapi_Entry* e, const char *type, long long + * \param type Attribute type in which you want to set the value. + * \param l Unsigned long value that you want to assign to the attribute. + */ +-void slapi_entry_attr_set_ulong(Slapi_Entry* e, const char *type, unsigned long l); ++void slapi_entry_attr_set_ulong(Slapi_Entry* e, const char *type, uint64_t l); + + /** + * Check if an attribute is set in the entry +@@ -6746,12 +6746,12 @@ void slapi_destroy_task(void *arg); + Slapi_Counter *slapi_counter_new(void); + void slapi_counter_init(Slapi_Counter *counter); + void slapi_counter_destroy(Slapi_Counter **counter); +-PRUint64 slapi_counter_increment(Slapi_Counter *counter); +-PRUint64 slapi_counter_decrement(Slapi_Counter *counter); +-PRUint64 slapi_counter_add(Slapi_Counter *counter, PRUint64 addvalue); +-PRUint64 slapi_counter_subtract(Slapi_Counter *counter, PRUint64 subvalue); +-PRUint64 slapi_counter_set_value(Slapi_Counter *counter, PRUint64 newvalue); +-PRUint64 slapi_counter_get_value(Slapi_Counter *counter); ++uint64_t slapi_counter_increment(Slapi_Counter *counter); ++uint64_t slapi_counter_decrement(Slapi_Counter *counter); ++uint64_t slapi_counter_add(Slapi_Counter *counter, uint64_t addvalue); ++uint64_t slapi_counter_subtract(Slapi_Counter *counter, uint64_t subvalue); ++uint64_t slapi_counter_set_value(Slapi_Counter *counter, uint64_t newvalue); ++uint64_t slapi_counter_get_value(Slapi_Counter *counter); + + /* Binder-based (connection centric) resource limits */ + /* +diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c +index c3ac846..9904fe9 100644 +--- a/ldap/servers/slapd/slapi_counter.c ++++ b/ldap/servers/slapd/slapi_counter.c +@@ -12,37 +12,21 @@ + + #include "slap.h" + +-#ifdef SOLARIS +-PRUint64 _sparcv9_AtomicSet(PRUint64 *address, PRUint64 newval); +-PRUint64 _sparcv9_AtomicAdd(PRUint64 *address, PRUint64 val); +-PRUint64 _sparcv9_AtomicSub(PRUint64 *address, PRUint64 val); ++#ifndef ATOMIC_64BIT_OPERATIONS ++#include + #endif + + #ifdef HPUX +-#ifdef ATOMIC_64BIT_OPERATIONS + #include + #endif +-#endif +- +-#ifdef ATOMIC_64BIT_OPERATIONS +-#if defined(LINUX) && !HAVE_64BIT_ATOMIC_OP_FUNCS +-/* On systems that don't have the 64-bit GCC atomic builtins, we need to +- * implement our own atomic functions using inline assembly code. */ +-PRUint64 __sync_add_and_fetch_8(PRUint64 *ptr, PRUint64 addval); +-PRUint64 __sync_sub_and_fetch_8(PRUint64 *ptr, PRUint64 subval); +-#define __sync_add_and_fetch __sync_add_and_fetch_8 +-#define __sync_sub_and_fetch __sync_sub_and_fetch_8 +-#endif +-#endif /* ATOMIC_64BIT_OPERATIONS */ +- + + /* + * Counter Structure + */ + typedef struct slapi_counter { +- PRUint64 value; ++ uint64_t value; + #ifndef ATOMIC_64BIT_OPERATIONS +- Slapi_Mutex *lock; ++ pthread_mutex_t _lock; + #endif + } slapi_counter; + +@@ -72,15 +56,11 @@ Slapi_Counter *slapi_counter_new() + void slapi_counter_init(Slapi_Counter *counter) + { + if (counter != NULL) { +-#ifndef ATOMIC_64BIT_OPERATIONS +- /* Create the lock if necessary. */ +- if (counter->lock == NULL) { +- counter->lock = slapi_new_mutex(); +- } +-#endif +- + /* Set the value to 0. */ + slapi_counter_set_value(counter, 0); ++#ifndef ATOMIC_64BIT_OPERATIONS ++ pthread_mutex_init(&(counter->_lock), NULL); ++#endif + } + } + +@@ -94,7 +74,7 @@ void slapi_counter_destroy(Slapi_Counter **counter) + { + if ((counter != NULL) && (*counter != NULL)) { + #ifndef ATOMIC_64BIT_OPERATIONS +- slapi_destroy_mutex((*counter)->lock); ++ pthread_mutex_destroy(&((*counter)->_lock)); + #endif + slapi_ch_free((void **)counter); + } +@@ -105,7 +85,7 @@ void slapi_counter_destroy(Slapi_Counter **counter) + * + * Atomically increments a Slapi_Counter. + */ +-PRUint64 slapi_counter_increment(Slapi_Counter *counter) ++uint64_t slapi_counter_increment(Slapi_Counter *counter) + { + return slapi_counter_add(counter, 1); + } +@@ -117,7 +97,7 @@ PRUint64 slapi_counter_increment(Slapi_Counter *counter) + * that this will not prevent you from wrapping + * around 0. + */ +-PRUint64 slapi_counter_decrement(Slapi_Counter *counter) ++uint64_t slapi_counter_decrement(Slapi_Counter *counter) + { + return slapi_counter_subtract(counter, 1); + } +@@ -127,28 +107,18 @@ PRUint64 slapi_counter_decrement(Slapi_Counter *counter) + * + * Atomically add a value to a Slapi_Counter. + */ +-PRUint64 slapi_counter_add(Slapi_Counter *counter, PRUint64 addvalue) ++uint64_t slapi_counter_add(Slapi_Counter *counter, uint64_t addvalue) + { +- PRUint64 newvalue = 0; +-#ifdef HPUX +- PRUint64 prev = 0; +-#endif ++ uint64_t newvalue = 0; + + if (counter == NULL) { + return newvalue; + } +- +-#ifndef ATOMIC_64BIT_OPERATIONS +- slapi_lock_mutex(counter->lock); +- counter->value += addvalue; +- newvalue = counter->value; +- slapi_unlock_mutex(counter->lock); ++#ifdef ATOMIC_64BIT_OPERATIONS ++ newvalue = __atomic_add_fetch_8(&(counter->value), addvalue, __ATOMIC_SEQ_CST); + #else +-#ifdef LINUX +- newvalue = __sync_add_and_fetch(&(counter->value), addvalue); +-#elif defined(SOLARIS) +- newvalue = _sparcv9_AtomicAdd(&(counter->value), addvalue); +-#elif defined(HPUX) ++#ifdef HPUX ++ uint64_t prev = 0; + /* fetchadd only works with values of 1, 4, 8, and 16. In addition, it requires + * it's argument to be an integer constant. */ + if (addvalue == 1) { +@@ -172,8 +142,13 @@ PRUint64 slapi_counter_add(Slapi_Counter *counter, PRUint64 addvalue) + _Asm_mov_to_ar(_AREG_CCV, prev); + } while (prev != _Asm_cmpxchg(_FASZ_D, _SEM_ACQ, &(counter->value), newvalue, _LDHINT_NONE)); + } ++#else ++ pthread_mutex_lock(&(counter->_lock)); ++ counter->value += addvalue; ++ newvalue = counter->value; ++ pthread_mutex_unlock(&(counter->_lock)); ++#endif + #endif +-#endif /* ATOMIC_64BIT_OPERATIONS */ + + return newvalue; + } +@@ -184,28 +159,19 @@ PRUint64 slapi_counter_add(Slapi_Counter *counter, PRUint64 addvalue) + * Atomically subtract a value from a Slapi_Counter. Note + * that this will not prevent you from wrapping around 0. + */ +-PRUint64 slapi_counter_subtract(Slapi_Counter *counter, PRUint64 subvalue) ++uint64_t slapi_counter_subtract(Slapi_Counter *counter, uint64_t subvalue) + { +- PRUint64 newvalue = 0; +-#ifdef HPUX +- PRUint64 prev = 0; +-#endif ++ uint64_t newvalue = 0; + + if (counter == NULL) { + return newvalue; + } + +-#ifndef ATOMIC_64BIT_OPERATIONS +- slapi_lock_mutex(counter->lock); +- counter->value -= subvalue; +- newvalue = counter->value; +- slapi_unlock_mutex(counter->lock); ++#ifdef ATOMIC_64BIT_OPERATIONS ++ newvalue = __atomic_sub_fetch_8(&(counter->value), subvalue, __ATOMIC_SEQ_CST); + #else +-#ifdef LINUX +- newvalue = __sync_sub_and_fetch(&(counter->value), subvalue); +-#elif defined(SOLARIS) +- newvalue = _sparcv9_AtomicSub(&(counter->value), subvalue); +-#elif defined(HPUX) ++#ifdef HPUX ++ uint64_t prev = 0; + /* fetchadd only works with values of -1, -4, -8, and -16. In addition, it requires + * it's argument to be an integer constant. */ + if (subvalue == 1) { +@@ -229,8 +195,13 @@ PRUint64 slapi_counter_subtract(Slapi_Counter *counter, PRUint64 subvalue) + _Asm_mov_to_ar(_AREG_CCV, prev); + } while (prev != _Asm_cmpxchg(_FASZ_D, _SEM_ACQ, &(counter->value), newvalue, _LDHINT_NONE)); + } ++#else ++ pthread_mutex_lock(&(counter->_lock)); ++ counter->value -= subvalue; ++ newvalue = counter->value; ++ pthread_mutex_unlock(&(counter->_lock)); ++#endif + #endif +-#endif /* ATOMIC_64BIT_OPERATIONS */ + + return newvalue; + } +@@ -240,76 +211,30 @@ PRUint64 slapi_counter_subtract(Slapi_Counter *counter, PRUint64 subvalue) + * + * Atomically sets the value of a Slapi_Counter. + */ +-PRUint64 slapi_counter_set_value(Slapi_Counter *counter, PRUint64 newvalue) ++uint64_t slapi_counter_set_value(Slapi_Counter *counter, uint64_t newvalue) + { +- PRUint64 value = 0; ++ uint64_t value = 0; + + if (counter == NULL) { + return value; + } + +-#ifndef ATOMIC_64BIT_OPERATIONS +- slapi_lock_mutex(counter->lock); +- counter->value = newvalue; +- slapi_unlock_mutex(counter->lock); +- return newvalue; +-#else +-#ifdef LINUX +-/* Use our own inline assembly for an atomic set if +- * the builtins aren't available. */ +-#if !HAVE_64BIT_ATOMIC_CAS_FUNC +- /* +- * %0 = counter->value +- * %1 = newvalue +- */ +- __asm__ __volatile__( +-#ifdef CPU_x86 +- /* Save the PIC register */ +- " pushl %%ebx;" +-#endif /* CPU_x86 */ +- /* Put value of counter->value in EDX:EAX */ +- "retryset: movl %0, %%eax;" +- " movl 4%0, %%edx;" +- /* Put newval in ECX:EBX */ +- " movl %1, %%ebx;" +- " movl 4+%1, %%ecx;" +- /* If EDX:EAX and counter-> are the same, +- * replace *ptr with ECX:EBX */ +- " lock; cmpxchg8b %0;" +- " jnz retryset;" +-#ifdef CPU_x86 +- /* Restore the PIC register */ +- " popl %%ebx" +-#endif /* CPU_x86 */ +- : "+o" (counter->value) +- : "m" (newvalue) +-#ifdef CPU_x86 +- : "memory", "eax", "ecx", "edx", "cc"); +-#else +- : "memory", "eax", "ebx", "ecx", "edx", "cc"); +-#endif +- +- return newvalue; +-#else +- while (1) { +- value = counter->value; +- if (__sync_bool_compare_and_swap(&(counter->value), value, newvalue)) { +- return newvalue; +- } +- } +-#endif /* CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH */ +-#elif defined(SOLARIS) +- _sparcv9_AtomicSet(&(counter->value), newvalue); +- return newvalue; +-#elif defined(HPUX) ++#ifdef ATOMIC_64BIT_OPERATIONS ++ __atomic_store_8(&(counter->value), newvalue, __ATOMIC_SEQ_CST); ++#else /* HPUX */ ++#ifdef HPUX + do { + value = counter->value; + /* Put value in a register for cmpxchg to compare against */ + _Asm_mov_to_ar(_AREG_CCV, value); + } while (value != _Asm_cmpxchg(_FASZ_D, _SEM_ACQ, &(counter->value), newvalue, _LDHINT_NONE)); +- return newvalue; ++#else ++ pthread_mutex_lock(&(counter->_lock)); ++ counter->value = newvalue; ++ pthread_mutex_unlock(&(counter->_lock)); ++#endif + #endif +-#endif /* ATOMIC_64BIT_OPERATIONS */ ++ return newvalue; + } + + /* +@@ -317,174 +242,30 @@ PRUint64 slapi_counter_set_value(Slapi_Counter *counter, PRUint64 newvalue) + * + * Returns the value of a Slapi_Counter. + */ +-PRUint64 slapi_counter_get_value(Slapi_Counter *counter) ++uint64_t slapi_counter_get_value(Slapi_Counter *counter) + { +- PRUint64 value = 0; ++ uint64_t value = 0; + + if (counter == NULL) { + return value; + } + +-#ifndef ATOMIC_64BIT_OPERATIONS +- slapi_lock_mutex(counter->lock); +- value = counter->value; +- slapi_unlock_mutex(counter->lock); +-#else +-#ifdef LINUX +-/* Use our own inline assembly for an atomic get if +- * the builtins aren't available. */ +-#if !HAVE_64BIT_ATOMIC_CAS_FUNC +- /* +- * %0 = counter->value +- * %1 = value +- */ +- __asm__ __volatile__( +-#ifdef CPU_x86 +- /* Save the PIC register */ +- " pushl %%ebx;" +-#endif /* CPU_x86 */ +- /* Put value of counter->value in EDX:EAX */ +- "retryget: movl %0, %%eax;" +- " movl 4%0, %%edx;" +- /* Copy EDX:EAX to ECX:EBX */ +- " movl %%eax, %%ebx;" +- " movl %%edx, %%ecx;" +- /* If EDX:EAX and counter->value are the same, +- * replace *ptr with ECX:EBX */ +- " lock; cmpxchg8b %0;" +- " jnz retryget;" +- /* Put retrieved value into value */ +- " movl %%ebx, %1;" +- " movl %%ecx, 4%1;" +-#ifdef CPU_x86 +- /* Restore the PIC register */ +- " popl %%ebx" +-#endif /* CPU_x86 */ +- : "+o" (counter->value), "=m" (value) +- : +-#ifdef CPU_x86 +- : "memory", "eax", "ecx", "edx", "cc"); +-#else +- : "memory", "eax", "ebx", "ecx", "edx", "cc"); +-#endif +-#else +- while (1) { +- value = counter->value; +- if (__sync_bool_compare_and_swap(&(counter->value), value, value)) { +- break; +- } +- } +-#endif /* CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH */ +-#elif defined(SOLARIS) +- while (1) { +- value = counter->value; +- if (value == _sparcv9_AtomicSet(&(counter->value), value)) { +- break; +- } +- } +-#elif defined(HPUX) ++#ifdef ATOMIC_64BIT_OPERATIONS ++ value = __atomic_load_8(&(counter->value), __ATOMIC_SEQ_CST); ++#else /* HPUX */ ++#ifdef HPUX + do { + value = counter->value; + /* Put value in a register for cmpxchg to compare against */ + _Asm_mov_to_ar(_AREG_CCV, value); + } while (value != _Asm_cmpxchg(_FASZ_D, _SEM_ACQ, &(counter->value), value, _LDHINT_NONE)); +-#endif +-#endif /* ATOMIC_64BIT_OPERATIONS */ +- +- return value; +-} +- +-#ifdef ATOMIC_64BIT_OPERATIONS +-#if defined(LINUX) && !HAVE_64BIT_ATOMIC_OP_FUNCS +-/* On systems that don't have the 64-bit GCC atomic builtins, we need to +- * implement our own atomic add and subtract functions using inline +- * assembly code. */ +-PRUint64 __sync_add_and_fetch_8(PRUint64 *ptr, PRUint64 addval) +-{ +- PRUint64 retval = 0; +- +- /* +- * %0 = *ptr +- * %1 = retval +- * %2 = addval +- */ +- __asm__ __volatile__( +-#ifdef CPU_x86 +- /* Save the PIC register */ +- " pushl %%ebx;" +-#endif /* CPU_x86 */ +- /* Put value of *ptr in EDX:EAX */ +- "retryadd: movl %0, %%eax;" +- " movl 4%0, %%edx;" +- /* Put addval in ECX:EBX */ +- " movl %2, %%ebx;" +- " movl 4+%2, %%ecx;" +- /* Add value from EDX:EAX to value in ECX:EBX */ +- " addl %%eax, %%ebx;" +- " adcl %%edx, %%ecx;" +- /* If EDX:EAX and *ptr are the same, replace ptr with ECX:EBX */ +- " lock; cmpxchg8b %0;" +- " jnz retryadd;" +- /* Put new value into retval */ +- " movl %%ebx, %1;" +- " movl %%ecx, 4%1;" +-#ifdef CPU_x86 +- /* Restore the PIC register */ +- " popl %%ebx" +-#endif /* CPU_x86 */ +- : "+o" (*ptr), "=m" (retval) +- : "m" (addval) +-#ifdef CPU_x86 +- : "memory", "eax", "ecx", "edx", "cc"); + #else +- : "memory", "eax", "ebx", "ecx", "edx", "cc"); ++ pthread_mutex_lock(&(counter->_lock)); ++ value = counter->value; ++ pthread_mutex_unlock(&(counter->_lock)); + #endif +- +- return retval; +-} +- +-PRUint64 __sync_sub_and_fetch_8(PRUint64 *ptr, PRUint64 subval) +-{ +- PRUint64 retval = 0; +- +- /* +- * %0 = *ptr +- * %1 = retval +- * %2 = subval +- */ +- __asm__ __volatile__( +-#ifdef CPU_x86 +- /* Save the PIC register */ +- " pushl %%ebx;" +-#endif /* CPU_x86 */ +- /* Put value of *ptr in EDX:EAX */ +- "retrysub: movl %0, %%eax;" +- " movl 4%0, %%edx;" +- /* Copy EDX:EAX to ECX:EBX */ +- " movl %%eax, %%ebx;" +- " movl %%edx, %%ecx;" +- /* Subtract subval from value in ECX:EBX */ +- " subl %2, %%ebx;" +- " sbbl 4+%2, %%ecx;" +- /* If EDX:EAX and ptr are the same, replace *ptr with ECX:EBX */ +- " lock; cmpxchg8b %0;" +- " jnz retrysub;" +- /* Put new value into retval */ +- " movl %%ebx, %1;" +- " movl %%ecx, 4%1;" +-#ifdef CPU_x86 +- /* Restore the PIC register */ +- " popl %%ebx" +-#endif /* CPU_x86 */ +- : "+o" (*ptr), "=m" (retval) +- : "m" (subval) +-#ifdef CPU_x86 +- : "memory", "eax", "ecx", "edx", "cc"); +-#else +- : "memory", "eax", "ebx", "ecx", "edx", "cc"); + #endif + +- return retval; ++ return value; + } +-#endif /* LINUX && !HAVE_64BIT_ATOMIC_OP_FUNCS */ +-#endif /* ATOMIC_64BIT_OPERATIONS */ ++ +diff --git a/ldap/servers/slapd/slapi_counter_sunos_sparcv9.S b/ldap/servers/slapd/slapi_counter_sunos_sparcv9.S +deleted file mode 100644 +index e582c2a..0000000 +--- a/ldap/servers/slapd/slapi_counter_sunos_sparcv9.S ++++ /dev/null +@@ -1,105 +0,0 @@ +-! BEGIN COPYRIGHT BLOCK +-! The Original Code is the Netscape Portable Runtime (NSPR). +-! +-! The Initial Developer of the Original Code is +-! Netscape Communications Corporation. +-! Portions created by the Initial Developer are Copyright (C) 1998-2000 +-! the Initial Developer. All Rights Reserved. +-! +-! The original code has been modified to support 64-bit atomic increments by +-! Red Hat, Inc. These portions are Copyright (C) 2008 Red Hat, Inc. All Rights +-! reserved. +-! +-! License: GPL (version 3 or any later version). +-! See LICENSE for details. +-! END COPYRIGHT BLOCK +-! +- +-#define _ASM 1 /* force to set an assembler code macro _ASM */ +-#include +- +-! ====================================================================== +-! +-! Perform the sequence a = b atomically with respect to other +-! fetch-and-stores to location a in a wait-free fashion. +-! +-! usage : old_val = PR_AtomicSet(address, newval) +-! +-! ----------------------- +-! Note on REGISTER USAGE: +-! as this is a LEAF procedure, a new stack frame is not created; +-! we use the caller's stack frame so what would normally be %i (input) +-! registers are actually %o (output registers). Also, we must not +-! overwrite the contents of %l (local) registers as they are not +-! assumed to be volatile during calls. +-! ----------------------- +- +- ENTRY(_sparcv9_AtomicSet) ! standard assembler/ELF prologue +- +-retryAS: +- ldx [%o0], %o2 ! set o2 to the current value +- mov %o1, %o3 ! set up the new value +- casx [%o0], %o2, %o3 ! atomically set if o0 hasn't changed +- cmp %o2, %o3 ! see if we set the value +- bne retryAS ! if not, try again +- nop ! empty out the branch pipeline +- retl ! return back to the caller +- mov %o3, %o0 ! set the return code to the prev value +- +- SET_SIZE(_sparcv9_AtomicSet) ! standard assembler/ELF epilogue +- +-! +-! end +-! +-! ====================================================================== +-! +-! Perform the sequence a = a + b atomically with respect to other +-! fetch-and-adds to location a in a wait-free fashion. +-! +-! usage : newval = PR_AtomicAdd(address, val) +-! return: the value after addition +-! +- ENTRY(_sparcv9_AtomicAdd) ! standard assembler/ELF prologue +- +-retryAA: +- ldx [%o0], %o2 ! set o2 to the current value +- addx %o2, %o1, %o3 ! calc the new value +- mov %o3, %o4 ! save the return value +- casx [%o0], %o2, %o3 ! atomically set if o0 hasn't changed +- cmp %o2, %o3 ! see if we set the value +- bne retryAA ! if not, try again +- nop ! empty out the branch pipeline +- retl ! return back to the caller +- mov %o4, %o0 ! set the return code to the new value +- +- SET_SIZE(_sparcv9_AtomicAdd) ! standard assembler/ELF epilogue +- +-! +-! end +-! +-! ====================================================================== +-! +-! Perform the sequence a = a - b atomically with respect to other +-! fetch-and-subs to location a in a wait-free fashion. +-! +-! usage : newval = PR_AtomicSub(address, val) +-! return: the value after addition +-! +- ENTRY(_sparcv9_AtomicSub) ! standard assembler/ELF prologue +- +-retryAU: +- ldx [%o0], %o2 ! set o2 to the current value +- subx %o2, %o1, %o3 ! calc the new value +- mov %o3, %o4 ! save the return value +- casx [%o0], %o2, %o3 ! atomically set if o0 hasn't changed +- cmp %o2, %o3 ! see if we set the value +- bne retryAU ! if not, try again +- nop ! empty out the branch pipeline +- retl ! return back to the caller +- mov %o4, %o0 ! set the return code to the new value +- +- SET_SIZE(_sparcv9_AtomicSub) ! standard assembler/ELF epilogue +- +-! +-! end +-! +diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c +index 841922f..b0c873d 100644 +--- a/ldap/servers/slapd/snmp_collator.c ++++ b/ldap/servers/slapd/snmp_collator.c +@@ -711,7 +711,7 @@ static void + add_counter_to_value(Slapi_Entry *e, const char *type, PRUint64 countervalue) + { + char value[40]; +- PR_snprintf(value,sizeof(value),"%" NSPRIu64, countervalue); ++ snprintf(value,sizeof(value),"%" NSPRIu64, countervalue); + slapi_entry_attr_set_charptr( e, type, value); + } + +diff --git a/test/libslapd/test.c b/test/libslapd/test.c +index 37d5543..6e1171a 100644 +--- a/test/libslapd/test.c ++++ b/test/libslapd/test.c +@@ -24,6 +24,8 @@ run_libslapd_tests (void) { + cmocka_unit_test(test_libslapd_pblock_v3c_original_target_dn), + cmocka_unit_test(test_libslapd_pblock_v3c_target_uniqueid), + cmocka_unit_test(test_libslapd_operation_v3c_target_spec), ++ cmocka_unit_test(test_libslapd_counters_atomic_usage), ++ cmocka_unit_test(test_libslapd_counters_atomic_overflow), + }; + return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/test/test_slapd.h b/test/test_slapd.h +index 02eefdd..b8f1aba 100644 +--- a/test/test_slapd.h ++++ b/test/test_slapd.h +@@ -37,4 +37,8 @@ void test_libslapd_pblock_v3c_target_uniqueid(void **state); + /* libslapd-operation-v3_compat */ + void test_libslapd_operation_v3c_target_spec(void **state); + ++/* libslapd-counters-atomic */ ++ ++void test_libslapd_counters_atomic_usage(void **state); ++void test_libslapd_counters_atomic_overflow(void **state); + +-- +2.9.3 + diff --git a/SOURCES/0016-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch b/SOURCES/0016-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch deleted file mode 100644 index c66717f..0000000 --- a/SOURCES/0016-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 70d236dedadc030fd2b450d7607b395b50523538 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 19 Oct 2017 17:02:20 -0400 -Subject: [PATCH] Ticket 49407 - status-dirsrv shows ellipsed lines - -Bug Description: To show the full output you have to pass "-l" to systemctl, - but there is no way to use this option with the current design. - -Fix Description: Just show the full lines by default, as adding options can break - the script's current usage. - -https://pagure.io/389-ds-base/issue/49407 - -Reviewed by: tbordaz(Thanks!) - -(cherry picked from commit 45d2fd4b50227687ad042a0e17d8dcd9e4cd3023) ---- - ldap/admin/src/scripts/status-dirsrv.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/admin/src/scripts/status-dirsrv.in b/ldap/admin/src/scripts/status-dirsrv.in -index 90428990b..8e492c115 100755 ---- a/ldap/admin/src/scripts/status-dirsrv.in -+++ b/ldap/admin/src/scripts/status-dirsrv.in -@@ -37,7 +37,7 @@ status_instance() { - # Use systemctl if available. - # - if [ -d "@systemdsystemunitdir@" ] && [ $(id -u) -eq 0 ];then -- @bindir@/systemctl status @package_name@@$SERV_ID.service -+ @bindir@/systemctl status @package_name@@$SERV_ID.service -l - rv=$? - if [ $rv -ne 0 ]; then - return 1 -@@ -65,7 +65,7 @@ found=0 - if [ $# -eq 0 ]; then - # We're reporting the status of all instances. - ret=0 -- @bindir@/systemctl status @package_name@.target -+ @bindir@/systemctl status @package_name@.target -l - initfiles=`get_initconfig_files $initconfig_dir` || { echo No instances found in $initconfig_dir ; exit 1 ; } - for i in $initfiles; do - inst=`normalize_server_id $i` --- -2.13.6 - diff --git a/SOURCES/0017-Issue-49035-dbmon.sh-shows-pages-in-use-that-exceeds.patch b/SOURCES/0017-Issue-49035-dbmon.sh-shows-pages-in-use-that-exceeds.patch new file mode 100644 index 0000000..bb75d3f --- /dev/null +++ b/SOURCES/0017-Issue-49035-dbmon.sh-shows-pages-in-use-that-exceeds.patch @@ -0,0 +1,38 @@ +From c14b2d88497724c4e19e5fae89bb40c95a61e1cb Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0017-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch b/SOURCES/0017-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch deleted file mode 100644 index bf19308..0000000 --- a/SOURCES/0017-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b7cca69de5f6cda32bc38504a7aa7e5bc786bbe6 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 19 Oct 2017 14:44:38 -0400 -Subject: [PATCH] Ticket 48681 - Use of uninitialized value in string ne at - /usr/bin/logconv.pl line 2565, <$LOGFH> line 4 - -Bug description: The original fix for 48681 added a regression in regards to perl - warning everytime you ran the script. That was due to a new hash - for sasl binds that was not initialized. - -Fix Description: Check is the saslbind hash "exists" before checking its value. - -https://pagure.io/389-ds-base/issue/48681 - -Reviewed by: mreynolds (one line fix) - -(cherry picked from commit e46749b77d95ad8fedf07d38890573b2862badf7) ---- - ldap/admin/src/logconv.pl | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl -index 4932db42e..473c71f21 100755 ---- a/ldap/admin/src/logconv.pl -+++ b/ldap/admin/src/logconv.pl -@@ -2562,7 +2562,7 @@ sub parseLineNormal - if ($_ =~ /conn= *([0-9A-Z]+) +op= *([0-9\-]+)/i){ - $conn = $1; - $op = $2; -- if ($hashes->{saslconnop}->{$conn-$op} ne ""){ -+ if (exists $hashes->{saslconnop}->{$conn-$op} && $hashes->{saslconnop}->{$conn-$op} ne ""){ - # This was a SASL BIND - record the dn - if ($binddn ne ""){ - if($binddn eq $rootDN){ $rootDNBindCount++; } --- -2.13.6 - diff --git a/SOURCES/0018-Issue-49177-Fix-pkg-config-file.patch b/SOURCES/0018-Issue-49177-Fix-pkg-config-file.patch new file mode 100644 index 0000000..143e956 --- /dev/null +++ b/SOURCES/0018-Issue-49177-Fix-pkg-config-file.patch @@ -0,0 +1,56 @@ +From a1c4718d9db069ab088914ec983af8125eba3ac6 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0018-Ticket-49374-server-fails-to-start-because-maxdisksi.patch b/SOURCES/0018-Ticket-49374-server-fails-to-start-because-maxdisksi.patch deleted file mode 100644 index 61ab747..0000000 --- a/SOURCES/0018-Ticket-49374-server-fails-to-start-because-maxdisksi.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 4ecec8dac601b77a25ebc390f138aad1ee48d805 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 19 Oct 2017 12:20:48 -0400 -Subject: [PATCH] Ticket 49374 - server fails to start because maxdisksize is - recognized incorrectly - -Bug Description: When directly editting dse.ldif, the server had a check - when setting the log maxdiskspace vs maxlogsize. If the - maxlogsize is processed first and it is higher than the - default maxdisksspace then it throw an error and the server - fails to start. - - If you attempt this same operation using ldapmodify it - works as "live" updates check all the mods first, so the - order of the attributes does not matter. - -Fix description: Remove the size checks from the attribute set function. - It is technically redundant since it is correctly checked - by the configdse code. - -https://pagure.io/389-ds-base/issue/49374 - -Reviewed by: tbordaz(Thanks!) - -(cherry picked from commit 63a0a59c9b09af08151831209ee6711b4363aee2) ---- - ldap/servers/slapd/log.c | 60 ++++++++++++------------------------------------ - 1 file changed, 15 insertions(+), 45 deletions(-) - -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index e16d89cc5..998efaef3 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -960,7 +960,6 @@ int - log_set_logsize(const char *attrname, char *logsize_str, int logtype, char *returntext, int apply) - { - int rv = LDAP_SUCCESS; -- PRInt64 mdiskspace = 0; /* in bytes */ - PRInt64 max_logsize; /* in bytes */ - int logsize; /* in megabytes */ - slapdFrontendConfig_t *fe_cfg = getFrontendConfig(); -@@ -979,72 +978,43 @@ log_set_logsize(const char *attrname, char *logsize_str, int logtype, char *retu - - switch (logtype) { - case SLAPD_ACCESS_LOG: -- LOG_ACCESS_LOCK_WRITE(); -- mdiskspace = loginfo.log_access_maxdiskspace; -- break; -- case SLAPD_ERROR_LOG: -- LOG_ERROR_LOCK_WRITE(); -- mdiskspace = loginfo.log_error_maxdiskspace; -- break; -- case SLAPD_AUDIT_LOG: -- LOG_AUDIT_LOCK_WRITE(); -- mdiskspace = loginfo.log_audit_maxdiskspace; -- break; -- case SLAPD_AUDITFAIL_LOG: -- LOG_AUDITFAIL_LOCK_WRITE(); -- mdiskspace = loginfo.log_auditfail_maxdiskspace; -- break; -- default: -- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -- "%s: invalid logtype %d", attrname, logtype); -- rv = LDAP_OPERATIONS_ERROR; -- } -- -- if ((max_logsize > mdiskspace) && (mdiskspace != -1)) { -- rv = 2; -- } -- -- switch (logtype) { -- case SLAPD_ACCESS_LOG: -- if (!rv && apply) { -+ if (apply) { -+ LOG_ACCESS_LOCK_WRITE(); - loginfo.log_access_maxlogsize = max_logsize; - fe_cfg->accesslog_maxlogsize = logsize; -+ LOG_ACCESS_UNLOCK_WRITE(); - } -- LOG_ACCESS_UNLOCK_WRITE(); - break; - case SLAPD_ERROR_LOG: -- if (!rv && apply) { -+ if (apply) { -+ LOG_ERROR_LOCK_WRITE(); - loginfo.log_error_maxlogsize = max_logsize; - fe_cfg->errorlog_maxlogsize = logsize; -+ LOG_ERROR_UNLOCK_WRITE(); - } -- LOG_ERROR_UNLOCK_WRITE(); - break; - case SLAPD_AUDIT_LOG: -- if (!rv && apply) { -+ if (apply) { -+ LOG_AUDIT_LOCK_WRITE(); - loginfo.log_audit_maxlogsize = max_logsize; - fe_cfg->auditlog_maxlogsize = logsize; -+ LOG_AUDIT_UNLOCK_WRITE(); - } -- LOG_AUDIT_UNLOCK_WRITE(); - break; - case SLAPD_AUDITFAIL_LOG: -- if (!rv && apply) { -+ if (apply) { -+ LOG_AUDITFAIL_LOCK_WRITE(); - loginfo.log_auditfail_maxlogsize = max_logsize; - fe_cfg->auditfaillog_maxlogsize = logsize; -+ LOG_AUDITFAIL_UNLOCK_WRITE(); - } -- LOG_AUDITFAIL_UNLOCK_WRITE(); - break; - default: -- rv = 1; -- } -- /* logsize is in MB */ -- if (rv == 2) { -- slapi_log_err(SLAPI_LOG_ERR, "log_set_logsize", -- "Invalid value for Maximum log size:" -- "Maxlogsize:%d (MB) exceeds Maxdisksize:%ld (MB)\n", -- logsize, (long int)(mdiskspace / LOG_MB_IN_BYTES)); -- -+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "%s: invalid logtype %d", attrname, logtype); - rv = LDAP_OPERATIONS_ERROR; - } -+ - return rv; - } - --- -2.13.6 - diff --git a/SOURCES/0019-Issue-49205-Fix-logconv.pl-man-page.patch b/SOURCES/0019-Issue-49205-Fix-logconv.pl-man-page.patch new file mode 100644 index 0000000..3520f71 --- /dev/null +++ b/SOURCES/0019-Issue-49205-Fix-logconv.pl-man-page.patch @@ -0,0 +1,1438 @@ +From 6cad70f25460f3ede0429ce11d5e60946acf1174 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 31 Mar 2017 11:23:50 -0400 +Subject: [PATCH] Issue 49205 - Fix logconv.pl man page + +Description: Fixed mistake in wording in the logconv.pl man page. Also + updated all the man pages with the new pagure ticket url. + +https://pagure.io/389-ds-base/issue/49205 + +Reviewed by: nhosoi(Thanks!) +--- + man/man1/cl-dump.1 | 6 +++--- + man/man1/dbgen.pl.1 | 6 +++--- + man/man1/dbscan.1 | 6 +++--- + man/man1/ds-logpipe.py.1 | 6 +++--- + man/man1/dsktune.1 | 6 +++--- + man/man1/infadd.1 | 6 +++--- + man/man1/ldap-agent.1 | 6 +++--- + man/man1/ldclt.1 | 6 +++--- + man/man1/ldif.1 | 6 +++--- + man/man1/logconv.pl.1 | 10 +++++----- + man/man1/migratecred.1 | 6 +++--- + man/man1/mmldif.1 | 6 +++--- + man/man1/pwdhash.1 | 6 +++--- + man/man1/readnsstate.1 | 6 +++--- + man/man1/repl-monitor.1 | 8 ++++---- + man/man1/rsearch.1 | 6 +++--- + man/man8/bak2db.8 | 6 +++--- + man/man8/bak2db.pl.8 | 6 +++--- + man/man8/cleanallruv.pl.8 | 6 +++--- + man/man8/db2bak.8 | 6 +++--- + man/man8/db2bak.pl.8 | 6 +++--- + man/man8/db2index.8 | 6 +++--- + man/man8/db2index.pl.8 | 6 +++--- + man/man8/db2ldif.8 | 6 +++--- + man/man8/db2ldif.pl.8 | 6 +++--- + man/man8/dbverify.8 | 6 +++--- + man/man8/dn2rdn.8 | 6 +++--- + man/man8/fixup-linkedattrs.pl.8 | 6 +++--- + man/man8/fixup-memberof.pl.8 | 6 +++--- + man/man8/ldif2db.8 | 6 +++--- + man/man8/ldif2db.pl.8 | 6 +++--- + man/man8/ldif2ldap.8 | 6 +++--- + man/man8/migrate-ds.pl.8 | 18 +++++++++--------- + man/man8/monitor.8 | 6 +++--- + man/man8/ns-accountstatus.pl.8 | 6 +++--- + man/man8/ns-activate.pl.8 | 6 +++--- + man/man8/ns-inactivate.pl.8 | 6 +++--- + man/man8/ns-newpwpolicy.pl.8 | 6 +++--- + man/man8/ns-slapd.8 | 6 +++--- + man/man8/remove-ds.pl.8 | 6 +++--- + man/man8/restart-dirsrv.8 | 6 +++--- + man/man8/restoreconfig.8 | 6 +++--- + man/man8/saveconfig.8 | 6 +++--- + man/man8/schema-reload.pl.8 | 6 +++--- + man/man8/setup-ds.pl.8 | 6 +++--- + man/man8/start-dirsrv.8 | 6 +++--- + man/man8/status-dirsrv.8 | 6 +++--- + man/man8/stop-dirsrv.8 | 6 +++--- + man/man8/suffix2instance.8 | 6 +++--- + man/man8/syntax-validate.pl.8 | 6 +++--- + man/man8/upgradedb.8 | 6 +++--- + man/man8/upgradednformat.8 | 6 +++--- + man/man8/usn-tombstone-cleanup.pl.8 | 6 +++--- + man/man8/verify-db.pl.8 | 6 +++--- + man/man8/vlvindex.8 | 6 +++--- + 55 files changed, 174 insertions(+), 174 deletions(-) + +diff --git a/man/man1/cl-dump.1 b/man/man1/cl-dump.1 +index f9dedbe..db736ac 100644 +--- a/man/man1/cl-dump.1 ++++ b/man/man1/cl-dump.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH CL-DUMP 1 "May 18, 2008" ++.TH CL-DUMP 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -81,11 +81,11 @@ is running, and from where the server's changelog directory is accessible. + .SH AUTHOR + cl-dump 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/dbgen.pl.1 b/man/man1/dbgen.pl.1 +index 6f25080..c238c9c 100644 +--- a/man/man1/dbgen.pl.1 ++++ b/man/man1/dbgen.pl.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH DBGEN.PL 1 "May 18, 2008" ++.TH DBGEN.PL 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -78,11 +78,11 @@ Add groups containing uniquemembers; generate a group for every 100 user entries + .SH AUTHOR + dbgen.pl 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/dbscan.1 b/man/man1/dbscan.1 +index e5ff0a7..641a3af 100644 +--- a/man/man1/dbscan.1 ++++ b/man/man1/dbscan.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH DBSCAN 1 "May 18, 2008" ++.TH DBSCAN 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -91,11 +91,11 @@ dbscan \fB\-f\fR objectclass.db4 + .SH AUTHOR + dbscan 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/ds-logpipe.py.1 b/man/man1/ds-logpipe.py.1 +index c7ea93d..0a6c15a 100644 +--- a/man/man1/ds-logpipe.py.1 ++++ b/man/man1/ds-logpipe.py.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH DS-LOGPIPE.PY 1 "November 24, 2009" ++.TH DS-LOGPIPE.PY 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -90,9 +90,9 @@ The error log and audit log have similarly named configuration attributes e.g. n + .SH AUTHOR + ds-logpipe.py 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 2009 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man1/dsktune.1 b/man/man1/dsktune.1 +index 19a6229..b3a5f7b 100644 +--- a/man/man1/dsktune.1 ++++ b/man/man1/dsktune.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH DSKTUNE 1 "May 18, 2008" ++.TH DSKTUNE 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -49,11 +49,11 @@ specify alternate server installation directory + .SH AUTHOR + dsktune 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/infadd.1 b/man/man1/infadd.1 +index 0969019..75c2f42 100644 +--- a/man/man1/infadd.1 ++++ b/man/man1/infadd.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH INFADD 1 "May 18, 2008" ++.TH INFADD 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -67,11 +67,11 @@ add binary blob of average size of bytes + .SH AUTHOR + infadd 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/ldap-agent.1 b/man/man1/ldap-agent.1 +index 50d80c3..f2d6576 100644 +--- a/man/man1/ldap-agent.1 ++++ b/man/man1/ldap-agent.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH LDAP-AGENT 1 "May 18, 2008" ++.TH LDAP-AGENT 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -44,11 +44,11 @@ Sample usage: + .SH AUTHOR + ldap\-agent 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/ldclt.1 b/man/man1/ldclt.1 +index 4105f42..451a88b 100644 +--- a/man/man1/ldclt.1 ++++ b/man/man1/ldclt.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH LDCLT 1 "May 18, 2008" ++.TH LDCLT 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -220,11 +220,11 @@ Execution parameters: + .SH AUTHOR + ldclt 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/ldif.1 b/man/man1/ldif.1 +index f5fa99b..c2398b4 100644 +--- a/man/man1/ldif.1 ++++ b/man/man1/ldif.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH LDIF 1 "May 18, 2008" ++.TH LDIF 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -40,11 +40,11 @@ ldif dn < /tmp/ldif + .SH AUTHOR + ldif 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/logconv.pl.1 b/man/man1/logconv.pl.1 +index e4c1d13..13db49f 100644 +--- a/man/man1/logconv.pl.1 ++++ b/man/man1/logconv.pl.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH LOGCONV.PL 1 "May 18, 2008" ++.TH LOGCONV.PL 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -38,7 +38,7 @@ DEFAULT \-> cn=directory manager + .B \fB\-D, \-\-data\fR + DEFAULT \-> /tmp + .br +-TIP \-> If there is not enough RAM, a RAM disk can be used instead: ++TIP \-> If there is enough RAM, a RAM disk can be used instead: + + mkdir /dev/shm/logconv, and use this directory for the "\-D" value. + .TP +@@ -115,7 +115,7 @@ Examples: + .IP + logconv.pl \fB\-s\fR 10 \fB\-V\fR access + .IP +-logconv.pl \fB\-d\fR "cn=directory manager" /export/server4/slapd\-host/logs/access* ++logconv.pl \fB\-d\fR "cn=directory manager" /var/log/dirsrv/slapd\-host/access* + .IP + logconv.pl \fB\-s\fR 50 \fB\-ibgju\fR access* + .IP +@@ -124,11 +124,11 @@ logconv.pl \fB\-S\fR "[28/Mar/2002:13:14:22 \fB\-0800]\fR" \fB\-E\fR "[28/Mar/20 + .SH AUTHOR + logconv.pl 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/migratecred.1 b/man/man1/migratecred.1 +index 50fbe0a..e935b5f 100644 +--- a/man/man1/migratecred.1 ++++ b/man/man1/migratecred.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH MIGRATECRED 1 "May 18, 2008" ++.TH MIGRATECRED 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -50,11 +50,11 @@ New plugin path (of the new instance) + .SH AUTHOR + migratecred 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/mmldif.1 b/man/man1/mmldif.1 +index e3f31ca..bde95d1 100644 +--- a/man/man1/mmldif.1 ++++ b/man/man1/mmldif.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH MMLDIF 1 "May 18, 2008" ++.TH MMLDIF 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -46,11 +46,11 @@ Write authoritative data to this file + .SH AUTHOR + mmldif 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/pwdhash.1 b/man/man1/pwdhash.1 +index 3ef5c9d..96194b3 100644 +--- a/man/man1/pwdhash.1 ++++ b/man/man1/pwdhash.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH PWDHASH 1 "May 18, 2008" ++.TH PWDHASH 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -47,11 +47,11 @@ Takes the password schema directly from the ns-slapd configuration + .SH AUTHOR + dbscan 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man1/readnsstate.1 b/man/man1/readnsstate.1 +index 0edf352..b18f49a 100644 +--- a/man/man1/readnsstate.1 ++++ b/man/man1/readnsstate.1 +@@ -1,4 +1,4 @@ +-.TH READNSSTATE 1 "May 13 2016" ++.TH READNSSTATE 1 "March 31, 2017" + .SH NAME + readnsstate \- interpret the contents of cn=replica's nsState value + .B readnsstate +@@ -38,9 +38,9 @@ For replica cn=replica,cn=dc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config + .SH AUTHOR + readnsstate was written by the 389 Project by richm. + .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 2016 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by William Brown , + for the 389 Directory Server Project. +diff --git a/man/man1/repl-monitor.1 b/man/man1/repl-monitor.1 +index 17b9c4b..2e4fc77 100644 +--- a/man/man1/repl-monitor.1 ++++ b/man/man1/repl-monitor.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH REPL-MONITOR 1 "Jun 28, 2016" ++.TH REPL-MONITOR 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -121,16 +121,16 @@ MY_SYSTEM2 = localhost2.localdomain:3892 + .SH AUTHOR + repl-monitor 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2016 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). + .br +-Manual page updated by Mark Reynolds 6/28/2016 ++Manual page updated by Mark Reynolds 3/31/2017 + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man1/rsearch.1 b/man/man1/rsearch.1 +index 319bfc1..ec269a5 100644 +--- a/man/man1/rsearch.1 ++++ b/man/man1/rsearch.1 +@@ -2,7 +2,7 @@ + .\" First parameter, NAME, should be all caps + .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection + .\" other parameters are allowed: see man(7), man(1) +-.TH RSEARCH 1 "May 18, 2008" ++.TH RSEARCH 1 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -123,11 +123,11 @@ Use \fB\-B\fR file for binding; ignored if \fB\-B\fR is not given + .SH AUTHOR + rsearch 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man8/bak2db.8 b/man/man8/bak2db.8 +index 77864728..74e5e58 100644 +--- a/man/man8/bak2db.8 ++++ b/man/man8/bak2db.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 BAK2DB 8 "Mar 5, 2013" ++.TH BAK2DB 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -57,6 +57,6 @@ to standard error. + .SH AUTHOR + bak2db 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/bak2db.pl.8 b/man/man8/bak2db.pl.8 +index 1bb76c5..01a41c1 100644 +--- a/man/man8/bak2db.pl.8 ++++ b/man/man8/bak2db.pl.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 BAK2DB.PL 8 "Mar 5, 2013" ++.TH BAK2DB.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -73,6 +73,6 @@ to standard error. + .SH AUTHOR + bak2db.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/cleanallruv.pl.8 b/man/man8/cleanallruv.pl.8 +index 55678ac..3afc688 100644 +--- a/man/man8/cleanallruv.pl.8 ++++ b/man/man8/cleanallruv.pl.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 CLEANALLRUV.PL 8 " Mar 5, 2013" ++.TH CLEANALLRUV.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -76,6 +76,6 @@ to standard error. + .SH AUTHOR + cleanallruv.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2bak.8 b/man/man8/db2bak.8 +index 5de017e..727867a 100644 +--- a/man/man8/db2bak.8 ++++ b/man/man8/db2bak.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 DB2BAK 8 "Mar 5, 2013" ++.TH DB2BAK 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -58,6 +58,6 @@ to standard error. + .SH AUTHOR + db2bak 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2bak.pl.8 b/man/man8/db2bak.pl.8 +index 9a34d51..a752885 100644 +--- a/man/man8/db2bak.pl.8 ++++ b/man/man8/db2bak.pl.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 DB2BAK.PL 8 "Mar 5, 2013" ++.TH DB2BAK.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -72,6 +72,6 @@ to standard error. + .SH AUTHOR + db2bak.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2index.8 b/man/man8/db2index.8 +index 1e70cc9..f70ba67 100644 +--- a/man/man8/db2index.8 ++++ b/man/man8/db2index.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 DB2INDEX 8 "Mar 5, 2013" ++.TH DB2INDEX 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -62,6 +62,6 @@ to standard error. + .SH AUTHOR + db2index 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2index.pl.8 b/man/man8/db2index.pl.8 +index 4ff9c7a..7297fae 100644 +--- a/man/man8/db2index.pl.8 ++++ b/man/man8/db2index.pl.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 DB2INDEX.PL 8 "Mar 5, 2013" ++.TH DB2INDEX.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -76,6 +76,6 @@ to standard error. + .SH AUTHOR + db2index.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2ldif.8 b/man/man8/db2ldif.8 +index 2a787f2..31f686b 100644 +--- a/man/man8/db2ldif.8 ++++ b/man/man8/db2ldif.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 DB2LDIF 8 "Mar 5, 2013" ++.TH DB2LDIF 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -101,6 +101,6 @@ to standard error. + .SH AUTHOR + db2ldif 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/db2ldif.pl.8 b/man/man8/db2ldif.pl.8 +index f02d3ed..babd225 100644 +--- a/man/man8/db2ldif.pl.8 ++++ b/man/man8/db2ldif.pl.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 DB2LDIF.PL 8 "Mar 5, 2013" ++.TH DB2LDIF.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -115,6 +115,6 @@ to standard error. + .SH AUTHOR + db2ldif.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/dbverify.8 b/man/man8/dbverify.8 +index c74747a..256e0aa 100644 +--- a/man/man8/dbverify.8 ++++ b/man/man8/dbverify.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 DBVERIFY 8 "Mar 5, 2013" ++.TH DBVERIFY 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -58,6 +58,6 @@ to standard error. + .SH AUTHOR + dbverify 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/dn2rdn.8 b/man/man8/dn2rdn.8 +index d6cd3cc..98d74da 100644 +--- a/man/man8/dn2rdn.8 ++++ b/man/man8/dn2rdn.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 DN2RDN 8 "Mar 5, 2013" ++.TH DN2RDN 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -53,6 +53,6 @@ to standard error. + .SH AUTHOR + dn2rdn 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/fixup-linkedattrs.pl.8 b/man/man8/fixup-linkedattrs.pl.8 +index ee484c8..1189cb8 100644 +--- a/man/man8/fixup-linkedattrs.pl.8 ++++ b/man/man8/fixup-linkedattrs.pl.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 FIXUP-LINKEDATTRS.PL 8 "Mar 5, 2013" ++.TH FIXUP-LINKEDATTRS.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -67,6 +67,6 @@ to standard error. + .SH AUTHOR + fixup-linkedattrs.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/fixup-memberof.pl.8 b/man/man8/fixup-memberof.pl.8 +index 55b7503..f80043c 100644 +--- a/man/man8/fixup-memberof.pl.8 ++++ b/man/man8/fixup-memberof.pl.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 FIXUP-MEMBEROF.PL 8 "Mar 5, 2013" ++.TH FIXUP-MEMBEROF.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -71,6 +71,6 @@ to standard error. + .SH AUTHOR + fixup-memberof.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ldif2db.8 b/man/man8/ldif2db.8 +index a5db3ea..9e3b149 100644 +--- a/man/man8/ldif2db.8 ++++ b/man/man8/ldif2db.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 LDIF2DB 8 "Mar 5, 2013" ++.TH LDIF2DB 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -84,6 +84,6 @@ to standard error. + .SH AUTHOR + ldif2db 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ldif2db.pl.8 b/man/man8/ldif2db.pl.8 +index cc3e316..3c02d03 100644 +--- a/man/man8/ldif2db.pl.8 ++++ b/man/man8/ldif2db.pl.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 LDIF2DB.PL 8 "Mar 5, 2013" ++.TH LDIF2DB.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -93,6 +93,6 @@ to standard error. + .SH AUTHOR + ldif2db.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ldif2ldap.8 b/man/man8/ldif2ldap.8 +index 117a1f7..b89f464 100644 +--- a/man/man8/ldif2ldap.8 ++++ b/man/man8/ldif2ldap.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 LDIF2LDAP 8 "Mar 5, 2013" ++.TH LDIF2LDAP 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -57,6 +57,6 @@ to standard error. + .SH AUTHOR + ldif2ldap 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/migrate-ds.pl.8 b/man/man8/migrate-ds.pl.8 +index 65a62d0..24eac5a 100644 +--- a/man/man8/migrate-ds.pl.8 ++++ b/man/man8/migrate-ds.pl.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 MIGRATE-DS.PL 8 "May 18, 2008" ++.TH MIGRATE-DS.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -121,15 +121,15 @@ for migration. Changelog information will not be migrated, and replicas + will need to be reinitialized (if migrating masters or hubs). This type + of migration requires that all of your old databases have been dumped + to LDIF format, and the LDIF file must be in the default database directory +-(usually /opt/fedora\-ds/slapd\-instance/db), and the LDIF file must have ++(usually /var/lib/dirsrv/slapd\-instance/db), and the LDIF file must have + the same name as the database instance directory, with a ".ldif". For + example, if you have + .IP + .ad l + .nf +-/opt/fedora\-ds/slapd\-instance/db/userRoot/ ++/var/lib/dirsrv/slapd\-instance/db/userRoot/ + and +-/opt/fedora\-ds/slapd\-instance/db/NetscapeRoot/ ++/var/lib/dirsrv/slapd\-instance/db/NetscapeRoot/ + .na + .fi + .PP +@@ -137,9 +137,9 @@ you must first use db2ldif to export these databases to LDIF e.g. + .IP + .ad l + .nf +-cd /opt/fedora\-ds/slapd\-instance +-\&./db2ldif \fB\-n\fR userRoot \fB\-a\fR /opt/fedora\-ds/slapd\-instance/db/userRoot.ldif and +-\&./db2ldif \fB\-n\fR NetscapeRoot \fB\-a\fR /opt/fedora\-ds/slapd\-instance/db/NetscapeRoot.ldif ++cd /var/lib/dirsrv/slapd\-instance ++\&./db2ldif \fB\-n\fR userRoot \fB\-a\fR /var/lib/dirsrv/slapd\-instance/ldif/userRoot.ldif and ++\&./db2ldif \fB\-n\fR NetscapeRoot \fB\-a\fR /var/lib/dirsrv/slapd\-instance/ldif/NetscapeRoot.ldif + .fi + .na + .PP +@@ -151,9 +151,9 @@ directory on the destination machine. + .SH AUTHOR + migrate-ds.pl 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 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man8/monitor.8 b/man/man8/monitor.8 +index 1cc2166..1e75fcf 100644 +--- a/man/man8/monitor.8 ++++ b/man/man8/monitor.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 MONITOR 8 "Mar 5, 2013" ++.TH MONITOR 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -62,6 +62,6 @@ to standard error. + .SH AUTHOR + monitor 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ns-accountstatus.pl.8 b/man/man8/ns-accountstatus.pl.8 +index 9ffc4d3..ceba3e6 100644 +--- a/man/man8/ns-accountstatus.pl.8 ++++ b/man/man8/ns-accountstatus.pl.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 NS-ACCOUNTSTATUS.PL 8 "Feb 8, 2016" ++.TH NS-ACCOUNTSTATUS.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -90,6 +90,6 @@ to standard error. + .SH AUTHOR + ns-accountstatus.pl 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 2016 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ns-activate.pl.8 b/man/man8/ns-activate.pl.8 +index 4b6f46d..2d4b82c 100644 +--- a/man/man8/ns-activate.pl.8 ++++ b/man/man8/ns-activate.pl.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 NS-ACTIVATE.PL 8 "Mar 5, 2013" ++.TH NS-ACTIVATE.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -68,6 +68,6 @@ to standard error. + .SH AUTHOR + ns-activate.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ns-inactivate.pl.8 b/man/man8/ns-inactivate.pl.8 +index 9e8ad77..f71a63f 100644 +--- a/man/man8/ns-inactivate.pl.8 ++++ b/man/man8/ns-inactivate.pl.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 NS-INACTIVATE.PL 8 "Mar 5, 2013" ++.TH NS-INACTIVATE.PL 8 "Mar 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -67,6 +67,6 @@ to standard error. + .SH AUTHOR + ns-inactivate.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ns-newpwpolicy.pl.8 b/man/man8/ns-newpwpolicy.pl.8 +index 1c38748..795bdc9 100644 +--- a/man/man8/ns-newpwpolicy.pl.8 ++++ b/man/man8/ns-newpwpolicy.pl.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 NS-NEWPWPOLICY.PL 8 "Mar 5, 2013" ++.TH NS-NEWPWPOLICY.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -74,6 +74,6 @@ to standard error. + .SH AUTHOR + ns-newpwpolicy.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/ns-slapd.8 b/man/man8/ns-slapd.8 +index 7c61533..96f995e 100644 +--- a/man/man8/ns-slapd.8 ++++ b/man/man8/ns-slapd.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 NS-SLAPD 8 "May 18, 2008" ++.TH NS-SLAPD 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -45,11 +45,11 @@ Specifies file where the pid of the process will be stored + .SH AUTHOR + ns-slapd 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 2001 Sun Microsystems, Inc. Used by permission. + .br +-Copyright \(co 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man8/remove-ds.pl.8 b/man/man8/remove-ds.pl.8 +index 0568ff8..5d60e47 100644 +--- a/man/man8/remove-ds.pl.8 ++++ b/man/man8/remove-ds.pl.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 REMOVE-DS.PL 8 "Feb 13, 2009" ++.TH REMOVE-DS.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -48,9 +48,9 @@ The full name of the instance to remove (e.g. slapd\(hyexample) + .SH AUTHOR + remove-ds.pl 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 2009 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man8/restart-dirsrv.8 b/man/man8/restart-dirsrv.8 +index c8af2ce..c82ec2b 100644 +--- a/man/man8/restart-dirsrv.8 ++++ b/man/man8/restart-dirsrv.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 RESTART-DIRSRV 8 "Jun 8, 2010" ++.TH RESTART-DIRSRV 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -40,9 +40,9 @@ Sample usage: + .SH AUTHOR + restart\-dirsrv 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 2010 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man8/restoreconfig.8 b/man/man8/restoreconfig.8 +index 18b27f5..97642b6 100644 +--- a/man/man8/restoreconfig.8 ++++ b/man/man8/restoreconfig.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 RESTORECONFIG 8 "Mar 5, 2013" ++.TH RESTORECONFIG 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -43,6 +43,6 @@ to standard error. + .SH AUTHOR + restoreconfig 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/saveconfig.8 b/man/man8/saveconfig.8 +index 8ba8a1d..1597043 100644 +--- a/man/man8/saveconfig.8 ++++ b/man/man8/saveconfig.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 SAVECONFIG 8 "Mar 5, 2013" ++.TH SAVECONFIG 8 "March 31, 2013" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -43,6 +43,6 @@ to standard error. + .SH AUTHOR + saveconfig 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/schema-reload.pl.8 b/man/man8/schema-reload.pl.8 +index 17380cf..85797f3 100644 +--- a/man/man8/schema-reload.pl.8 ++++ b/man/man8/schema-reload.pl.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 SCHEMA-RELOAD.PL 8 "Mar 5, 2013" ++.TH SCHEMA-RELOAD.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -65,6 +65,6 @@ to standard error. + .SH AUTHOR + schema-reload.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/setup-ds.pl.8 b/man/man8/setup-ds.pl.8 +index 11e0966..b491e18 100644 +--- a/man/man8/setup-ds.pl.8 ++++ b/man/man8/setup-ds.pl.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 SETUP-DS.PL 8 "May 18, 2008" ++.TH SETUP-DS.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -103,9 +103,9 @@ Offline \- servers \fBmust be shutdown\fR - no username or password required + .SH AUTHOR + setup-ds.pl 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 2008 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This manual page was written by Michele Baldessari , + for the Debian project (but may be used by others). +diff --git a/man/man8/start-dirsrv.8 b/man/man8/start-dirsrv.8 +index f34da66..34f3988 100644 +--- a/man/man8/start-dirsrv.8 ++++ b/man/man8/start-dirsrv.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 START-DIRSRV 8 "Jun 8, 2010" ++.TH START-DIRSRV 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -40,9 +40,9 @@ Sample usage: + .SH AUTHOR + start\-dirsrv 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 2010 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man8/status-dirsrv.8 b/man/man8/status-dirsrv.8 +index 83844b3..862c871 100644 +--- a/man/man8/status-dirsrv.8 ++++ b/man/man8/status-dirsrv.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 STATUS-DIRSRV 8 "Jan 20, 2016" ++.TH STATUS-DIRSRV 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -45,9 +45,9 @@ If a single Directory Server instance is specified, 0 is returned if the instanc + .SH AUTHOR + status\-dirsrv 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 2016 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man8/stop-dirsrv.8 b/man/man8/stop-dirsrv.8 +index 08bf493..fdca0a9 100644 +--- a/man/man8/stop-dirsrv.8 ++++ b/man/man8/stop-dirsrv.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 STOP-DIRSRV 8 "Jun 8, 2010" ++.TH STOP-DIRSRV 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -40,9 +40,9 @@ Sample usage: + .SH AUTHOR + stop\-dirsrv 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 2010 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + .br + This is free software. You may redistribute copies of it under the terms of + the Directory Server license found in the LICENSE file of this +diff --git a/man/man8/suffix2instance.8 b/man/man8/suffix2instance.8 +index 8e30f4a..0e4cf69 100644 +--- a/man/man8/suffix2instance.8 ++++ b/man/man8/suffix2instance.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 SUFFIX2INSTANCE 8 "Mar 5, 2013" ++.TH SUFFIX2INSTANCE 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -46,6 +46,6 @@ to standard error. + .SH AUTHOR + suffix2instance 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/syntax-validate.pl.8 b/man/man8/syntax-validate.pl.8 +index ece2d59..d34c49d 100644 +--- a/man/man8/syntax-validate.pl.8 ++++ b/man/man8/syntax-validate.pl.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 SYNTAX-VALIDATE.PL 8 "Mar 5, 2013" ++.TH SYNTAX-VALIDATE.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -68,6 +68,6 @@ to standard error. + .SH AUTHOR + syntax-validate.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/upgradedb.8 b/man/man8/upgradedb.8 +index 495c722..70d1c5f 100644 +--- a/man/man8/upgradedb.8 ++++ b/man/man8/upgradedb.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 UPGRADEDB 8 "Mar 5, 2013" ++.TH UPGRADEDB 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -50,7 +50,7 @@ to standard error. + .SH AUTHOR + upgradedb 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. + +diff --git a/man/man8/upgradednformat.8 b/man/man8/upgradednformat.8 +index 3f3f58f..7513994 100644 +--- a/man/man8/upgradednformat.8 ++++ b/man/man8/upgradednformat.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 UPGRADEDNFORMAT 8 "Mar 5, 2013" ++.TH UPGRADEDNFORMAT 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -50,6 +50,6 @@ to standard error. + .SH AUTHOR + upgradednformat 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/usn-tombstone-cleanup.pl.8 b/man/man8/usn-tombstone-cleanup.pl.8 +index f78b230..c5aabc5 100644 +--- a/man/man8/usn-tombstone-cleanup.pl.8 ++++ b/man/man8/usn-tombstone-cleanup.pl.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 USN-TOMBSTONE-CLEANUP.PL 8 "Mar 5, 2013" ++.TH USN-TOMBSTONE-CLEANUP.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -71,6 +71,6 @@ to standard error. + .SH AUTHOR + usn-tombstone-cleanup.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/verify-db.pl.8 b/man/man8/verify-db.pl.8 +index 500b713..0de3af5 100644 +--- a/man/man8/verify-db.pl.8 ++++ b/man/man8/verify-db.pl.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 VERIFY-DB.PL 8 "Mar 5, 2013" ++.TH VERIFY-DB.PL 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -44,6 +44,6 @@ to standard error. + .SH AUTHOR + verify-db.pl 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +diff --git a/man/man8/vlvindex.8 b/man/man8/vlvindex.8 +index 154f1c2..f3e1748 100644 +--- a/man/man8/vlvindex.8 ++++ b/man/man8/vlvindex.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 VLVINDEX 8 "Mar 5, 2013" ++.TH VLVINDEX 8 "March 31, 2017" + .\" Please adjust this date whenever revising the manpage. + .\" + .\" Some roff macros, for reference: +@@ -53,6 +53,6 @@ to standard error. + .SH AUTHOR + vlvindex 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 2013 Red Hat, Inc. ++Copyright \(co 2017 Red Hat, Inc. +-- +2.9.3 + diff --git a/SOURCES/0019-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch b/SOURCES/0019-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch deleted file mode 100644 index d92ffd6..0000000 --- a/SOURCES/0019-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch +++ /dev/null @@ -1,66 +0,0 @@ -From ef4ac2d45c9ea99fbb1ae6cee97745161f193bf9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 25 Oct 2017 10:53:28 -0400 -Subject: [PATCH] Ticket 48681 - Use of uninitialized value in string ne at - /usr/bin/logconv.pl - -Bug Description: ldapi connections were not properly porcessed by the - connection parsing code which lead to uninitialized errors. - -Fix Description: Modify the connection IP address regex's to include "local" - -https://pagure.io/389-ds-base/issue/48681 - -Reviewd by: mreynolds (one line commit rule) - -(cherry picked from commit 6098e7b927b64ba300567e71ea611140c47676a1) ---- - ldap/admin/src/logconv.pl | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl -index 473c71f21..e36386e11 100755 ---- a/ldap/admin/src/logconv.pl -+++ b/ldap/admin/src/logconv.pl -@@ -809,9 +809,9 @@ if ($totalTimeInNsecs == 0){ - print "Restarts: $serverRestartCount\n"; - - if(%cipher){ -- print " Secure Protocol Versions:\n"; -+ print "Secure Protocol Versions:\n"; - foreach my $key (sort { $b cmp $a } keys %cipher) { -- print " - $key - $cipher{$key}\n"; -+ print " - $key ($cipher{$key} connections)\n"; - } - print "\n"; - } -@@ -1754,7 +1754,7 @@ parseLineBind { - ($end) = $endTime =~ /\D*(\S*)/; - } - } -- if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ) { -+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ) { - my $skip = "yes"; - for (my $excl =0; $excl < $#excludeIP; $excl++){ - if ($excludeIP[$excl] eq $1){ -@@ -2085,7 +2085,7 @@ sub parseLineNormal - } - if (m/ connection from/){ - my $ip; -- if ($_ =~ /connection from *([0-9A-Fa-f\.\:]+)/i ){ -+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ){ - $ip = $1; - for (my $xxx =0; $xxx < $#excludeIP; $xxx++){ - if ($excludeIP[$xxx] eq $ip){$exc = "yes";} -@@ -2253,7 +2253,7 @@ sub parseLineNormal - } - if ($usage =~ /g/ || $usage =~ /c/ || $usage =~ /i/ || $usage =~ /f/ || $usage =~ /u/ || $usage =~ /U/ || $verb eq "yes"){ - $exc = "no"; -- if ($_ =~ /connection from *([0-9A-fa-f\.\:]+)/i ) { -+ if ($_ =~ /connection from *([0-9A-Za-z\.\:]+)/i ) { - for (my $xxx = 0; $xxx < $#excludeIP; $xxx++){ - if ($1 eq $excludeIP[$xxx]){ - $exc = "yes"; --- -2.13.6 - diff --git a/SOURCES/0020-Issue-49039-password-min-age-should-be-ignored-if-pa.patch b/SOURCES/0020-Issue-49039-password-min-age-should-be-ignored-if-pa.patch new file mode 100644 index 0000000..68aedd6 --- /dev/null +++ b/SOURCES/0020-Issue-49039-password-min-age-should-be-ignored-if-pa.patch @@ -0,0 +1,121 @@ +From 578d207cd66e97e9ff8211559c62114a961e35a8 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0020-Ticket-49401-improve-valueset-sorted-performance-on-.patch b/SOURCES/0020-Ticket-49401-improve-valueset-sorted-performance-on-.patch deleted file mode 100644 index 657dfe6..0000000 --- a/SOURCES/0020-Ticket-49401-improve-valueset-sorted-performance-on-.patch +++ /dev/null @@ -1,250 +0,0 @@ -From a59b2f4129565dbfa1b63899dd550e9c22b02923 Mon Sep 17 00:00:00 2001 -From: Mohammad Nweider -Date: Wed, 18 Oct 2017 13:02:15 +0000 -Subject: [PATCH] Ticket 49401 - improve valueset sorted performance on delete - -Bug Description: valueset sorted maintains a list of syntax sorted -references to the attributes of the entry. During addition these are -modified and added properly, so they stay sorted. - -However, in the past to maintain the sorted property, during a delete -we would need to remove the vs->sorted array, and recreate it via qsort, - -While this was an improvement from past (where we would removed -vs->sorted during an attr delete), it still has performance implications -on very very large datasets, IE 50,000 member groups with -addition/deletion, large entry caches and replication. - -Fix Description: Implement a new algorithm that is able to maintain -existing sort data in a near linear time. - -https://pagure.io/389-ds-base/issue/49401 - -Author: nweiderm, wibrown - -Review by: wibrown, lkrispen, tbordaz (Thanks nweiderm!) - -(cherry picked from commit a43a8efc7907116146b505ac40f18fac71f474b0) ---- - ldap/servers/slapd/valueset.c | 171 +++++++++++++++++++++++++----------------- - 1 file changed, 103 insertions(+), 68 deletions(-) - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index d2c67d2fb..1c1bc150a 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -677,100 +677,136 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn) - size_t i = 0; - size_t j = 0; - int nextValue = 0; -+ int nv = 0; - int numValues = 0; -+ Slapi_Value **va2 = NULL; -+ int *sorted2 = NULL; - - /* Loop over all the values freeing the old ones. */ -- for (i = 0; i < vs->num; i++) { -+ for(i = 0; i < vs->num; i++) -+ { - /* If we have the sorted array, find the va array ref by it. */ - if (vs->sorted) { - j = vs->sorted[i]; - } else { - j = i; - } -- csnset_purge(&(vs->va[j]->v_csnset), csn); -- if (vs->va[j]->v_csnset == NULL) { -- slapi_value_free(&vs->va[j]); -- vs->va[j] = NULL; -- } else if (vs->va[j] != NULL) { -- /* This value survived, we should count it. */ -- numValues++; -+ if (vs->va[j]) { -+ csnset_purge(&(vs->va[j]->v_csnset),csn); -+ if (vs->va[j]->v_csnset == NULL) { -+ slapi_value_free(&vs->va[j]); -+ /* Set the removed value to NULL so we know later to skip it */ -+ vs->va[j] = NULL; -+ if (vs->sorted) { -+ /* Mark the value in sorted for removal */ -+ vs->sorted[i] = -1; -+ } -+ } else { -+ /* This value survived, we should count it. */ -+ numValues++; -+ } - } - } - -- /* Now compact the value/sorted list. */ -+ /* Compact vs->va and vs->sorted only when there're -+ * remaining values ie: numValues is greater than 0 */ - /* -- * Because we want to preserve the sorted array, this is complicated. -+ * Algorithm explination: We start with a pair of arrays - the attrs, and the sorted array that provides -+ * a lookup into it: -+ * -+ * va: [d e a c b] sorted: [2 4 3 0 1] -+ * -+ * When we remove the element b, we NULL it, and we have to mark the place where it "was" as a -1 to -+ * flag it's removal. -+ * -+ * va: [d e a c NULL] sorted: [2 -1 3 0 1] -+ * -+ * Now a second va is created with the reduced allocation, -+ * -+ * va2: [ X X X X ] .... -+ * -+ * Now we loop over sorted, skipping -1 that we find. In a new counter we create new sorted -+ * references, and move the values compacting them in the process. -+ * va: [d e a c NULL] -+ * va2: [a x x x] -+ * sorted: [_0 -1 3 0 1] -+ * -+ * Looping a few more times would yield: - * -- * We have an array of values: -- * [ b, a, c, NULL, e, NULL, NULL, d] -- * And an array of indicies that are sorted. -- * [ 1, 0, 2, 7, 4, 3, 5, 6 ] -- * Were we to iterate over the sorted array, we get refs to the values in -- * some order. -- * The issue is now we must *remove* from both the values *and* the sorted. -+ * va2: [a c x x] -+ * sorted: [_0 _1 3 0 1] - * -- * Previously, we just discarded this, because too hard. Now we try to keep -- * it. The issue is that this is surprisingly hard to actually keep in -- * sync. -+ * va2: [a c d x] -+ * sorted: [_0 _1 _2 0 1] - * -- * We can't just blindly move the values down: That breaks the sorted array -- * and we would need to iterate over the sorted array multiple times to -- * achieve this. -+ * va2: [a c d e] -+ * sorted: [_0 _1 _2 _3 1] -+ * -+ * Not only does this sort va, but with sorted, we have a faster lookup, and it will benefit cache -+ * lookup. - * -- * It's actually going to be easier to just ditch the sorted, compact vs -- * and then qsort the array. - */ -+ if (numValues > 0) { -+ if(vs->sorted) { -+ /* Let's allocate va2 and sorted2 */ -+ va2 = (Slapi_Value **) slapi_ch_malloc( (numValues + 1) * sizeof(Slapi_Value *)); -+ sorted2 = (int *) slapi_ch_malloc( (numValues + 1)* sizeof(int)); -+ } - -- j = 0; -- while (nextValue < numValues && j < vs->num) { -- /* nextValue is what we are looking at now -- * j tracks along the array getting next elements. -- * -- * [ b, a, c, NULL, e, NULL, NULL, d] -- * ^nv ^j -- * [ b, a, c, e, NULL, NULL, NULL, d] -- * ^nv ^j -- * [ b, a, c, e, NULL, NULL, NULL, d] -- * ^nv ^j -- * [ b, a, c, e, NULL, NULL, NULL, d] -- * ^nv ^j -- * [ b, a, c, e, NULL, NULL, NULL, d] -- * ^nv ^j -- * [ b, a, c, e, d, NULL, NULL, NULL] -- * ^nv ^j -- */ -- if (vs->va[nextValue] == NULL) { -- /* Advance j till we find something */ -- while (vs->va[j] == NULL) { -- j++; -+ /* I is the index for the *new* va2 array */ -+ for(i=0; inum; i++) { -+ if (vs->sorted) { -+ /* Skip any removed values from the index */ -+ while((nv < vs->num) && (-1 == vs->sorted[nv])) { -+ nv++; -+ } -+ /* We have a remaining value, add it to the va */ -+ if(nv < vs->num) { -+ va2[i] = vs->va[vs->sorted[nv]]; -+ sorted2[i] = i; -+ nv++; -+ } -+ } else { -+ while((nextValue < vs->num) && (NULL == vs->va[nextValue])) { -+ nextValue++; -+ } -+ -+ if(nextValue < vs->num) { -+ vs->va[i] = vs->va[nextValue]; -+ nextValue++; -+ } else { -+ break; -+ } - } -- /* We have something! */ -- vs->va[nextValue] = vs->va[j]; -- vs->va[j] = NULL; - } -- nextValue++; -- } -- /* Fix up the number of values */ -- vs->num = numValues; -- /* Should we re-alloc values to be smaller? */ -- /* Other parts of DS are lazy. Lets clean our list */ -- for (j = vs->num; j < vs->max; j++) { -- vs->va[j] = NULL; -- } - -- /* All the values were deleted, we can discard the whole array. */ -- if (vs->num == 0) { - if (vs->sorted) { -+ /* Finally replace the valuearray and adjust num, max */ -+ slapi_ch_free((void **)&vs->va); - slapi_ch_free((void **)&vs->sorted); -+ vs->va = va2; -+ vs->sorted = sorted2; -+ vs->num = numValues; -+ vs->max = vs->num + 1; -+ } else { -+ vs->num = numValues; - } -- slapi_ch_free((void **)&vs->va); -- vs->va = NULL; -- vs->max = 0; -- } else if (vs->sorted != NULL) { -- /* We still have values! rebuild the sorted array */ -- valueset_array_to_sorted(a, vs); -+ -+ for (j = vs->num; j < vs->max; j++) { -+ vs->va[j] = NULL; -+ if (vs->sorted) { -+ vs->sorted[j] = -1; -+ } -+ } -+ } else { -+ slapi_valueset_done(vs); - } - -+ /* We still have values but not sorted array! rebuild it */ -+ if(vs->num > VALUESET_ARRAY_SORT_THRESHOLD && vs->sorted == NULL) { -+ vs->sorted = (int *) slapi_ch_malloc( vs->max* sizeof(int)); -+ valueset_array_to_sorted(a, vs); -+ } - #ifdef DEBUG - PR_ASSERT(vs->num == 0 || (vs->num > 0 && vs->va[0] != NULL)); - size_t index = 0; -@@ -781,7 +817,6 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn) - PR_ASSERT(vs->va[index] == NULL); - } - #endif -- - /* return the number of remaining values */ - return numValues; - } --- -2.13.6 - diff --git a/SOURCES/0021-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch b/SOURCES/0021-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch deleted file mode 100644 index 8438d01..0000000 --- a/SOURCES/0021-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 308691e03cc6312bde3409b346df3156d34db0fe Mon Sep 17 00:00:00 2001 -From: Mohammad Nweider -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 -(cherry picked from commit 52ba2aba49935989152010aee0d40b01d7a78432) ---- - ldap/servers/slapd/valueset.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index 1c1bc150a..dc0360738 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -680,7 +680,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn) - int nv = 0; - int numValues = 0; - Slapi_Value **va2 = NULL; -- int *sorted2 = NULL; -+ size_t *sorted2 = NULL; - - /* Loop over all the values freeing the old ones. */ - for(i = 0; i < vs->num; i++) -@@ -750,7 +750,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn) - if(vs->sorted) { - /* Let's allocate va2 and sorted2 */ - va2 = (Slapi_Value **) slapi_ch_malloc( (numValues + 1) * sizeof(Slapi_Value *)); -- sorted2 = (int *) slapi_ch_malloc( (numValues + 1)* sizeof(int)); -+ sorted2 = (size_t *) slapi_ch_malloc( (numValues + 1)* sizeof(size_t)); - } - - /* I is the index for the *new* va2 array */ -@@ -804,7 +804,7 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn) - - /* We still have values but not sorted array! rebuild it */ - if(vs->num > VALUESET_ARRAY_SORT_THRESHOLD && vs->sorted == NULL) { -- vs->sorted = (int *) slapi_ch_malloc( vs->max* sizeof(int)); -+ vs->sorted = (size_t *) slapi_ch_malloc( vs->max* sizeof(size_t)); - valueset_array_to_sorted(a, vs); - } - #ifdef DEBUG --- -2.13.6 - diff --git a/SOURCES/0021-fix-for-cve-2017-2668-simple-return-text-if-suffix-n.patch b/SOURCES/0021-fix-for-cve-2017-2668-simple-return-text-if-suffix-n.patch new file mode 100644 index 0000000..15f6cd2 --- /dev/null +++ b/SOURCES/0021-fix-for-cve-2017-2668-simple-return-text-if-suffix-n.patch @@ -0,0 +1,110 @@ +From ea60248d99abb8fed9f7a2b1ab7325c5523b8562 Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +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 +--- + 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 + diff --git a/SOURCES/0022-Issue-47662-CLI-args-get-removed.patch b/SOURCES/0022-Issue-47662-CLI-args-get-removed.patch new file mode 100644 index 0000000..6bd0608 --- /dev/null +++ b/SOURCES/0022-Issue-47662-CLI-args-get-removed.patch @@ -0,0 +1,63 @@ +From 3937047eee31638df068b3294aa90ef603915676 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0022-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch b/SOURCES/0022-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch deleted file mode 100644 index 8e2be67..0000000 --- a/SOURCES/0022-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dba89dd23d2d62686de192e0986eba65270a62c7 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 26 Oct 2017 10:03:39 -0400 -Subject: [PATCH] Ticket 48894 - harden valueset_array_to_sorted_quick valueset - access - -Description: It's possible during the sorting of a valueset to access an - array element past the allocated size, and also go below the index 0. - -https://pagure.io/389-ds-base/issue/48894 - -Reviewed by: nweiderm (Thanks!) - -(cherry picked from commit 2086d052e338ddcbcf6bd3222617991641573a12) ---- - ldap/servers/slapd/valueset.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index dc0360738..14ebc48e6 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -1019,11 +1019,11 @@ valueset_array_to_sorted_quick(const Slapi_Attr *a, Slapi_ValueSet *vs, size_t l - while (1) { - do { - i++; -- } while (valueset_value_cmp(a, vs->va[vs->sorted[i]], vs->va[pivot]) < 0); -+ } while (i < vs->max && valueset_value_cmp(a, vs->va[vs->sorted[i]], vs->va[pivot]) < 0); - - do { - j--; -- } while (valueset_value_cmp(a, vs->va[vs->sorted[j]], vs->va[pivot]) > 0); -+ } while (valueset_value_cmp(a, vs->va[vs->sorted[j]], vs->va[pivot]) > 0 && j > 0); - - if (i >= j) { - break; --- -2.13.6 - diff --git a/SOURCES/0023-Issue-49210-Fix-regression-when-checking-is-password.patch b/SOURCES/0023-Issue-49210-Fix-regression-when-checking-is-password.patch new file mode 100644 index 0000000..850d829 --- /dev/null +++ b/SOURCES/0023-Issue-49210-Fix-regression-when-checking-is-password.patch @@ -0,0 +1,141 @@ +From 5854fc41c6620567f0356e382baec4eda1e645b2 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0023-Ticket-49424-Resolve-csiphash-alignment-issues.patch b/SOURCES/0023-Ticket-49424-Resolve-csiphash-alignment-issues.patch deleted file mode 100644 index 5dde249..0000000 --- a/SOURCES/0023-Ticket-49424-Resolve-csiphash-alignment-issues.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 5909e20899334816f36cac0e47105e56df52ad3c Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Mon, 30 Oct 2017 12:01:34 +1000 -Subject: [PATCH] Ticket 49424 - Resolve csiphash alignment issues - -Bug Description: On some platforms, uint64_t is not the same size -as a void * - as well, if the input is not aligned correctly, then -a number of nasty crashes can result - -Fix Description: Instead of relying on alignment to be correct, -we should memcpy the data to inputs instead. - -https://pagure.io/389-ds-base/issue/49424 - -Author: wibrown - -Review by: lslebodn, cgrzemba, vashirov, mreynolds (Thanks!) - -(cherry picked from commit 751446440f5269a246e6e652a64e63aa5933734a) ---- - src/libsds/external/csiphash/csiphash.c | 52 +++++++++++++++++++-------------- - src/libsds/test/test_sds_csiphash.c | 43 +++++++++++++++++++++------ - 2 files changed, 64 insertions(+), 31 deletions(-) - -diff --git a/src/libsds/external/csiphash/csiphash.c b/src/libsds/external/csiphash/csiphash.c -index 0089c82f7..2351db6cf 100644 ---- a/src/libsds/external/csiphash/csiphash.c -+++ b/src/libsds/external/csiphash/csiphash.c -@@ -32,6 +32,9 @@ - #include - #include /* for size_t */ - -+#include /* calloc,free */ -+#include /* memcpy */ -+ - #include - - #if defined(HAVE_SYS_ENDIAN_H) -@@ -75,11 +78,24 @@ - uint64_t - sds_siphash13(const void *src, size_t src_sz, const char key[16]) - { -- const uint64_t *_key = (uint64_t *)key; -+ uint64_t _key[2] = {0}; -+ memcpy(_key, key, 16); - uint64_t k0 = _le64toh(_key[0]); - uint64_t k1 = _le64toh(_key[1]); - uint64_t b = (uint64_t)src_sz << 56; -- const uint64_t *in = (uint64_t *)src; -+ -+ size_t input_sz = (src_sz / sizeof(uint64_t)) + 1; -+ -+ /* Account for non-uint64_t alligned input */ -+ /* Could make this stack allocation */ -+ uint64_t *in = calloc(1, input_sz * sizeof(uint64_t)); -+ /* -+ * Because all crypto code sucks, they modify *in -+ * during operation, so we stash a copy of the ptr here. -+ * alternately, we could use stack allocated array, but gcc -+ * will complain about the vla being unbounded. -+ */ -+ uint64_t *in_ptr = memcpy(in, src, src_sz); - - uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; - uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; -@@ -96,27 +112,15 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16]) - v0 ^= mi; - } - -+ /* -+ * Because we allocate in as size + 1, we can over-read 0 -+ * for this buffer to be padded correctly. in here is a pointer to the -+ * excess data because the while loop above increments the in pointer -+ * to point to the excess once src_sz drops < 8. -+ */ - uint64_t t = 0; -- uint8_t *pt = (uint8_t *)&t; -- uint8_t *m = (uint8_t *)in; -- -- switch (src_sz) { -- case 7: -- pt[6] = m[6]; /* FALLTHRU */ -- case 6: -- pt[5] = m[5]; /* FALLTHRU */ -- case 5: -- pt[4] = m[4]; /* FALLTHRU */ -- case 4: -- *((uint32_t *)&pt[0]) = *((uint32_t *)&m[0]); -- break; -- case 3: -- pt[2] = m[2]; /* FALLTHRU */ -- case 2: -- pt[1] = m[1]; /* FALLTHRU */ -- case 1: -- pt[0] = m[0]; /* FALLTHRU */ -- } -+ memcpy(&t, in, sizeof(uint64_t)); -+ - b |= _le64toh(t); - - v3 ^= b; -@@ -126,5 +130,9 @@ sds_siphash13(const void *src, size_t src_sz, const char key[16]) - v2 ^= 0xff; - // dround - dROUND(v0, v1, v2, v3); -+ -+ free(in_ptr); -+ - return (v0 ^ v1) ^ (v2 ^ v3); - } -+ -diff --git a/src/libsds/test/test_sds_csiphash.c b/src/libsds/test/test_sds_csiphash.c -index cdb6b7f46..cc9a6b2b5 100644 ---- a/src/libsds/test/test_sds_csiphash.c -+++ b/src/libsds/test/test_sds_csiphash.c -@@ -25,23 +25,48 @@ - static void - test_siphash(void **state __attribute__((unused))) - { -- -- // - uint64_t value = 0; - uint64_t hashout = 0; - char key[16] = {0}; - -- uint64_t test_a = 15794382300316794652U; -- uint64_t test_b = 13042610424265326907U; -+ uint64_t test_simple = 15794382300316794652U; - -- // Initial simple test -+ /* Initial simple test */ - value = htole64(5); - hashout = sds_siphash13(&value, sizeof(uint64_t), key); -- assert_true(hashout == test_a); -+ assert_int_equal(hashout, test_simple); -+ -+ /* Test a range of input sizes to check endianness behaviour */ -+ -+ hashout = sds_siphash13("a", 1, key); -+ assert_int_equal(hashout, 0x407448d2b89b1813U); -+ -+ hashout = sds_siphash13("aa", 2, key); -+ assert_int_equal(hashout, 0x7910e0436ed8d1deU); -+ -+ hashout = sds_siphash13("aaa", 3, key); -+ assert_int_equal(hashout, 0xf752893a6c769652U); -+ -+ hashout = sds_siphash13("aaaa", 4, key); -+ assert_int_equal(hashout, 0x8b02350718d87164U); -+ -+ hashout = sds_siphash13("aaaaa", 5, key); -+ assert_int_equal(hashout, 0x92a991474c7eef2U); -+ -+ hashout = sds_siphash13("aaaaaa", 6, key); -+ assert_int_equal(hashout, 0xf0ab815a640277ccU); -+ -+ hashout = sds_siphash13("aaaaaaa", 7, key); -+ assert_int_equal(hashout, 0x33f3c6d7dbc82c0dU); -+ -+ hashout = sds_siphash13("aaaaaaaa", 8, key); -+ assert_int_equal(hashout, 0xc501b12e18428c92U); -+ -+ hashout = sds_siphash13("aaaaaaaabbbb", 12, key); -+ assert_int_equal(hashout, 0xcddca673069ade64U); - -- char *test = "abc"; -- hashout = sds_siphash13(test, 4, key); -- assert_true(hashout == test_b); -+ hashout = sds_siphash13("aaaaaaaabbbbbbbb", 16, key); -+ assert_int_equal(hashout, 0xdc54f0bfc0e1deb0U); - } - - int --- -2.13.6 - diff --git a/SOURCES/0024-Ticket-49209-Hang-due-to-omitted-replica-lock-releas.patch b/SOURCES/0024-Ticket-49209-Hang-due-to-omitted-replica-lock-releas.patch new file mode 100644 index 0000000..e10387c --- /dev/null +++ b/SOURCES/0024-Ticket-49209-Hang-due-to-omitted-replica-lock-releas.patch @@ -0,0 +1,42 @@ +From 765520fa7bf49f2de542d619b0fce99e13e4d53a Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0024-Ticket-49436-double-free-in-COS-in-some-conditions.patch b/SOURCES/0024-Ticket-49436-double-free-in-COS-in-some-conditions.patch deleted file mode 100644 index 4309a5f..0000000 --- a/SOURCES/0024-Ticket-49436-double-free-in-COS-in-some-conditions.patch +++ /dev/null @@ -1,258 +0,0 @@ -From dcf75750dff23e848cde2ae63a0778b123de6dd7 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Thu, 2 Nov 2017 13:32:41 +1000 -Subject: [PATCH] Ticket 49436 - double free in COS in some conditions - -Bug Description: virtualattrs and COS have some serious memory -ownership issues. What was happening is that COS with multiple -attributes using the same sp_handle would cause a structure -to be registered twice. During shutdown we would then trigger -a double free in the process. - -Fix Description: Change the behaviour of sp_handles to use a -handle *per* attribute we register to guarantee the assocation -between them. - -https://pagure.io/389-ds-base/issue/49436 - -Author: wibrown - -Review by: mreynolds, vashirov (Thanks!) - -(cherry pick from commit ee4428a3f5d2d8e37a7107c7dce9d622fc17d41c) ---- - dirsrvtests/tests/suites/cos/indirect_cos_test.py | 43 +++++++---------------- - ldap/servers/plugins/cos/cos_cache.c | 32 +++++++++-------- - ldap/servers/plugins/roles/roles_cache.c | 8 ++--- - ldap/servers/slapd/vattr.c | 28 +++++++++------ - 4 files changed, 51 insertions(+), 60 deletions(-) - -diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py -index 1aac6b8ed..452edcdf8 100644 ---- a/dirsrvtests/tests/suites/cos/indirect_cos_test.py -+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py -@@ -7,6 +7,7 @@ import subprocess - - from lib389 import Entry - from lib389.idm.user import UserAccounts -+from lib389.idm.domain import Domain - from lib389.topologies import topology_st as topo - from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE, - SERVERID_STANDALONE, PORT_STANDALONE) -@@ -48,14 +49,8 @@ def check_user(inst): - def setup_subtree_policy(topo): - """Set up subtree password policy - """ -- try: -- topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, -- 'nsslapd-pwpolicy-local', -- 'on')]) -- except ldap.LDAPError as e: -- log.error('Failed to set fine-grained policy: error {}'.format( -- e.message['desc'])) -- raise e -+ -+ topo.standalone.config.set('nsslapd-pwpolicy-local', 'on') - - log.info('Create password policy for subtree {}'.format(OU_PEOPLE)) - try: -@@ -68,15 +63,9 @@ def setup_subtree_policy(topo): - OU_PEOPLE, e.message['desc'])) - raise e - -- log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE)) -- try: -- topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE, -- 'pwdpolicysubentry', -- PW_POLICY_CONT_PEOPLE2)]) -- except ldap.LDAPError as e: -- log.error('Failed to pwdpolicysubentry pw policy ' -- 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc'])) -- raise e -+ domain = Domain(topo.standalone, DEFAULT_SUFFIX) -+ domain.replace('pwdpolicysubentry', PW_POLICY_CONT_PEOPLE2) -+ - time.sleep(1) - - -@@ -116,12 +105,9 @@ def setup(topo, request): - """ - log.info('Add custom schema...') - try: -- ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " + -- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -- ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " + -- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -- OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " + -- "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )") -+ ATTR_1 = (b"( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -+ ATTR_2 = (b"( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") -+ OC = (b"( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY ( x-department $ x-en-ou ) X-ORIGIN 'user defined' )") - topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1), - (ldap.MOD_ADD, 'attributeTypes', ATTR_2), - (ldap.MOD_ADD, 'objectClasses', OC)]) -@@ -142,14 +128,9 @@ def setup(topo, request): - 'homeDirectory': '/home/test_user', - 'seeAlso': 'cn=cosTemplate,dc=example,dc=com' - } -- users.create(properties=user_properties) -- try: -- topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD, -- 'objectclass', -- 'xPerson')]) -- except ldap.LDAPError as e: -- log.fatal('Failed to add objectclass to user') -- raise e -+ user = users.create(properties=user_properties) -+ -+ user.add('objectClass', 'xPerson') - - # Setup COS - log.info("Setup indirect COS...") -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index 9ae15db15..662dace35 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -109,9 +109,6 @@ void *cos_get_plugin_identity(void); - #define COSTYPE_INDIRECT 3 - #define COS_DEF_ERROR_NO_TEMPLATES -2 - --/* the global plugin handle */ --static volatile vattr_sp_handle *vattr_handle = NULL; -- - /* both variables are protected by change_lock */ - static int cos_cache_notify_flag = 0; - static PRBool cos_cache_at_work = PR_FALSE; -@@ -323,16 +320,6 @@ cos_cache_init(void) - views_api = 0; - } - -- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, -- cos_cache_vattr_get, -- cos_cache_vattr_compare, -- cos_cache_vattr_types) != 0) { -- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, -- "cos_cache_init - Cannot register as service provider\n"); -- ret = -1; -- goto out; -- } -- - if (PR_CreateThread(PR_USER_THREAD, - cos_cache_wait_on_change, - NULL, -@@ -860,8 +847,23 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data) - dnVals[valIndex]->bv_val); - } - -- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, -- dnVals[valIndex]->bv_val, NULL, NULL); -+ /* -+ * Each SP_handle is associated to one and only one vattr. -+ * We could consider making this a single function rather -+ * than the double-call. -+ */ -+ -+ vattr_sp_handle *vattr_handle = NULL; -+ -+ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, -+ cos_cache_vattr_get, -+ cos_cache_vattr_compare, -+ cos_cache_vattr_types) != 0) { -+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val); -+ } else { -+ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); -+ } -+ - } /* if(attrType is cosAttribute) */ - - /* -diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c -index 59f5a6081..1e5865af8 100644 ---- a/ldap/servers/plugins/roles/roles_cache.c -+++ b/ldap/servers/plugins/roles/roles_cache.c -@@ -47,9 +47,6 @@ static char *allUserAttributes[] = { - /* views scoping */ - static void **views_api; - --/* Service provider handler */ --static vattr_sp_handle *vattr_handle = NULL; -- - /* List of nested roles */ - typedef struct _role_object_nested - { -@@ -224,6 +221,10 @@ roles_cache_init() - so that we update the corresponding cache */ - slapi_register_backend_state_change(NULL, roles_cache_trigger_update_suffix); - -+ /* Service provider handler - only used once! and freed by vattr! */ -+ vattr_sp_handle *vattr_handle = NULL; -+ -+ - if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, - roles_sp_get_value, - roles_sp_compare_value, -@@ -622,7 +623,6 @@ roles_cache_stop() - current_role = next_role; - } - slapi_rwlock_unlock(global_lock); -- slapi_ch_free((void **)&vattr_handle); - roles_list = NULL; - - slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<-- roles_cache_stop\n"); -diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c -index 82deb41fe..432946c79 100644 ---- a/ldap/servers/slapd/vattr.c -+++ b/ldap/servers/slapd/vattr.c -@@ -1864,7 +1864,12 @@ vattr_map_create(void) - void - vattr_map_entry_free(vattr_map_entry *vae) - { -- slapi_ch_free((void **)&(vae->sp_list)); -+ vattr_sp_handle *list_entry = vae->sp_list; -+ while (list_entry != NULL) { -+ vattr_sp_handle *next_entry = list_entry->next; -+ slapi_ch_free((void **)&list_entry); -+ list_entry = next_entry; -+ } - slapi_ch_free_string(&(vae->type_name)); - slapi_ch_free((void **)&vae); - } -@@ -2143,16 +2148,9 @@ slapi_vattr_schema_check_type(Slapi_Entry *e, char *type) - vattr_map_entry * - vattr_map_entry_new(char *type_name, vattr_sp_handle *sph, void *hint) - { -- vattr_map_entry *result = NULL; -- vattr_sp_handle *sp_copy = NULL; -- -- sp_copy = (vattr_sp_handle *)slapi_ch_calloc(1, sizeof(vattr_sp_handle)); -- sp_copy->sp = sph->sp; -- sp_copy->hint = hint; -- -- result = (vattr_map_entry *)slapi_ch_calloc(1, sizeof(vattr_map_entry)); -+ vattr_map_entry *result = (vattr_map_entry *)slapi_ch_calloc(1, sizeof(vattr_map_entry)); - result->type_name = slapi_ch_strdup(type_name); -- result->sp_list = sp_copy; -+ result->sp_list = sph; - - /* go get schema */ - result->objectclasses = vattr_map_entry_build_schema(type_name); -@@ -2273,6 +2271,16 @@ we'd need to hold a lock on the read path, which we don't want to do. - So any SP which relinquishes its need to handle a type needs to continue - to handle the calls on it, but return nothing */ - /* DBDB need to sort out memory ownership here, it's not quite right */ -+/* -+ * This function was inconsistent. We would allocated and "kind of", -+ * copy the sp_handle here for the vattr_map_entry_new path. But we -+ * would "take ownership" for the existing entry and the list addition -+ * path. Instead now, EVERY sp_handle we take, we take ownership of -+ * and the CALLER must allocate a new one each time. -+ * -+ * Better idea, is that regattr should just take the fn pointers -+ * and callers never *see* the sp_handle structure at all. -+ */ - - int - vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint) --- -2.13.6 - diff --git a/SOURCES/0025-Ticket-48393-Improve-replication-config-validation.patch b/SOURCES/0025-Ticket-48393-Improve-replication-config-validation.patch deleted file mode 100644 index 748eb78..0000000 --- a/SOURCES/0025-Ticket-48393-Improve-replication-config-validation.patch +++ /dev/null @@ -1,1719 +0,0 @@ -From c1ac23d7f5f6f14d75bd02cfd55818e2558f7cb9 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 3 Nov 2017 09:30:01 -0400 -Subject: [PATCH] Ticket 48393 - Improve replication config validation - -Bug Description: There was inconsistent behavior when modifying and adding replication - configurations and agreements. There were also a few places where - unsigned ints were used for values which made checking for negative - values impossible. - -Fix Description: Added a new function to properly check "number" attribute values. - Also forced failure on the actual update if an invalid value was used - (previously we would log an error and use some default value). Also - made all the int types consistent. - -https://pagure.io/389-ds-base/issue/48393 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit f6b0e1841059460d6d0071cc771e3fbe834af393) ---- - .../suites/replication/replica_config_test.py | 397 +++++++++++++++++++++ - ldap/schema/01core389.ldif | 3 +- - ldap/servers/plugins/replication/repl5.h | 54 +-- - ldap/servers/plugins/replication/repl5_agmt.c | 173 +++++---- - ldap/servers/plugins/replication/repl5_replica.c | 280 +++++++++------ - .../plugins/replication/repl5_replica_config.c | 158 ++++---- - ldap/servers/plugins/replication/replutil.c | 26 ++ - 7 files changed, 792 insertions(+), 299 deletions(-) - create mode 100644 dirsrvtests/tests/suites/replication/replica_config_test.py - -diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py -new file mode 100644 -index 000000000..50ea2ece9 ---- /dev/null -+++ b/dirsrvtests/tests/suites/replication/replica_config_test.py -@@ -0,0 +1,397 @@ -+import logging -+import pytest -+import copy -+import os -+import ldap -+from lib389._constants import * -+from lib389 import Entry -+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__) -+ -+REPLICA_DN = 'cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config' -+AGMT_DN = 'cn=test_agreement,cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config' -+notnum = 'invalid' -+too_big = '9223372036854775807' -+overflow = '9999999999999999999999999999999999999999999999999999999999999999999' -+ -+replica_dict = {'objectclass': 'top nsDS5Replica'.split(), -+ 'nsDS5ReplicaRoot': 'dc=example,dc=com', -+ 'nsDS5ReplicaType': '3', -+ 'nsDS5Flags': '1', -+ 'nsDS5ReplicaId': '65535', -+ 'nsds5ReplicaPurgeDelay': '604800', -+ 'nsDS5ReplicaBindDN': 'cn=u', -+ 'cn': 'replica'} -+ -+agmt_dict = {'objectClass': 'top nsDS5ReplicationAgreement'.split(), -+ 'cn': 'test_agreement', -+ 'nsDS5ReplicaRoot': 'dc=example,dc=com', -+ 'nsDS5ReplicaHost': 'localhost.localdomain', -+ 'nsDS5ReplicaPort': '5555', -+ 'nsDS5ReplicaBindDN': 'uid=tester', -+ 'nsds5ReplicaCredentials': 'password', -+ 'nsDS5ReplicaTransportInfo': 'LDAP', -+ 'nsDS5ReplicaBindMethod': 'SIMPLE'} -+ -+ -+repl_add_attrs = [('nsDS5ReplicaType', '-1', '4', overflow, notnum, '1'), -+ ('nsDS5Flags', '-1', '2', overflow, notnum, '1'), -+ ('nsDS5ReplicaId', '0', '65536', overflow, notnum, '1'), -+ ('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'), -+ ('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'), -+ ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')] -+ -+repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'), -+ ('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'), -+ ('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'), -+ ('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'), -+ ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')] -+ -+agmt_attrs = [('nsds5ReplicaPort', '0', '65536', overflow, notnum, '389'), -+ ('nsds5ReplicaTimeout', '-1', too_big, overflow, notnum, '6'), -+ ('nsds5ReplicaBusyWaitTime', '-1', too_big, overflow, notnum, '6'), -+ ('nsds5ReplicaSessionPauseTime', '-1', too_big, overflow, notnum, '6'), -+ ('nsds5ReplicaFlowControlWindow', '-1', too_big, overflow, notnum, '6'), -+ ('nsds5ReplicaFlowControlPause', '-1', too_big, overflow, notnum, '6'), -+ ('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '6')] -+ -+ -+def replica_setup(topo): -+ """Add a valid replica config entry to modify -+ """ -+ try: -+ topo.standalone.delete_s(REPLICA_DN) -+ except: -+ pass -+ -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, replica_dict))) -+ except ldap.LDAPError as e: -+ log.fatal("Failed to add replica entry: " + str(e)) -+ assert False -+ -+ -+def replica_reset(topo): -+ try: -+ topo.standalone.delete_s(REPLICA_DN) -+ except: -+ pass -+ -+ -+def agmt_setup(topo): -+ """Add a valid replica config entry to modify -+ """ -+ try: -+ topo.standalone.delete_s(AGMT_DN) -+ except: -+ pass -+ -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, agmt_dict))) -+ except ldap.LDAPError as e: -+ log.fatal("Failed to add agreement entry: " + str(e)) -+ assert False -+ -+ -+def agmt_reset(topo): -+ try: -+ topo.standalone.delete_s(AGMT_DN) -+ except: -+ pass -+ -+ -+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", repl_add_attrs) -+def test_replica_num_add(topo, attr, too_small, too_big, overflow, notnum, valid): -+ """Test all the number values you can set for a replica config entry -+ -+ :id: a8b47d4a-a089-4d70-8070-e6181209bf92 -+ :setup: standalone instance -+ :steps: -+ 1. Use a value that is too small -+ 2. Use a value that is too big -+ 3. Use a value that overflows the int -+ 4. Use a value with character value (not a number) -+ 5. Use a valid value -+ :expectedresults: -+ 1. Add is rejected -+ 2. Add is rejected -+ 3. Add is rejected -+ 4. Add is rejected -+ 5. Add is allowed -+ """ -+ -+ replica_reset(topo) -+ -+ # Test too small -+ my_replica = copy.deepcopy(replica_dict) -+ my_replica[attr] = too_small -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, my_replica))) -+ log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, too_small)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add replica entry with {}:{} error: {}".format(attr, too_small, str(e))) -+ -+ # Test too big -+ my_replica = copy.deepcopy(replica_dict) -+ my_replica[attr] = too_big -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, my_replica))) -+ log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, too_big)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add replica entry with {}:{} error: {}".format(attr, too_big, str(e))) -+ -+ # Test overflow -+ my_replica = copy.deepcopy(replica_dict) -+ my_replica[attr] = overflow -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, my_replica))) -+ log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, overflow)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add replica entry with {}:{} error: {}".format(attr, overflow, str(e))) -+ -+ # test not a number -+ my_replica = copy.deepcopy(replica_dict) -+ my_replica[attr] = notnum -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, my_replica))) -+ log.fatal("Incorrectly allowed to add replica entry with {}:{}".format(attr, notnum)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add replica entry with {}:{} error: {}".format(attr, notnum, str(e))) -+ -+ # Test valid value -+ my_replica = copy.deepcopy(replica_dict) -+ my_replica[attr] = valid -+ try: -+ topo.standalone.add_s(Entry((REPLICA_DN, my_replica))) -+ log.info("Correctly allowed to add replica entry with {}: {}".format(attr, valid)) -+ except ldap.LDAPError as e: -+ log.fatal("Incorrectly failed to add replica entry with {}: {} error: {}".format(attr, valid, str(e))) -+ assert False -+ -+ -+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", repl_mod_attrs) -+def test_replica_num_modify(topo, attr, too_small, too_big, overflow, notnum, valid): -+ """Test all the number values you can set for a replica config entry -+ -+ :id: a8b47d4a-a089-4d70-8070-e6181209bf93 -+ :setup: standalone instance -+ :steps: -+ 1. Replace a value that is too small -+ 2. Repalce a value that is too big -+ 3. Replace a value that overflows the int -+ 4. Replace a value with character value (not a number) -+ 5. Replace a vlue with a valid value -+ :expectedresults: -+ 1. Value is rejected -+ 2. Value is rejected -+ 3. Value is rejected -+ 4. Value is rejected -+ 5. Value is allowed -+ """ -+ -+ # Value too small -+ replica_setup(topo) -+ try: -+ topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, too_small)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_small)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_small)) -+ -+ # Value too big -+ replica_setup(topo) -+ try: -+ topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, too_big)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_big)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_big)) -+ -+ # Value overflow -+ replica_setup(topo) -+ try: -+ topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, overflow)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, overflow)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, overflow)) -+ -+ # Value not a number -+ replica_setup(topo) -+ try: -+ topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, notnum)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, notnum)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, notnum)) -+ -+ # Value is valid -+ replica_setup(topo) -+ try: -+ topo.standalone.modify_s(REPLICA_DN, [(ldap.MOD_REPLACE, attr, valid)]) -+ log.info('Correctly added valid agreement attribute value: {}:{}'.format(attr, valid)) -+ except ldap.LDAPError as e: -+ log.fatal('Valid value for {}:{} was incorrectly rejected. Error {}'.format(attr, valid, str(e))) -+ assert False -+ -+ -+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", agmt_attrs) -+def test_agmt_num_add(topo, attr, too_small, too_big, overflow, notnum, valid): -+ """Test all the number values you can set for a replica config entry -+ -+ :id: a8b47d4a-a089-4d70-8070-e6181209bf94 -+ :setup: standalone instance -+ :steps: -+ 1. Use a value that is too small -+ 2. Use a value that is too big -+ 3. Use a value that overflows the int -+ 4. Use a value with character value (not a number) -+ 5. Use a valid value -+ :expectedresults: -+ 1. Add is rejected -+ 2. Add is rejected -+ 3. Add is rejected -+ 4. Add is rejected -+ 5. Add is allowed -+ """ -+ agmt_reset(topo) -+ -+ # Test too small -+ my_agmt = copy.deepcopy(agmt_dict) -+ my_agmt[attr] = too_small -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, my_agmt))) -+ log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, too_small)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add agreement entry with {}:{} error: {}".format(attr, too_small, str(e))) -+ -+ # Test too big -+ my_agmt = copy.deepcopy(agmt_dict) -+ my_agmt[attr] = too_big -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, my_agmt))) -+ log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, too_big)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add agreement entry with {}:{} error: {}".format(attr, too_big, str(e))) -+ -+ # Test overflow -+ my_agmt = copy.deepcopy(agmt_dict) -+ my_agmt[attr] = overflow -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, my_agmt))) -+ log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, overflow)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add agreement entry with {}:{} error: {}".format(attr, overflow, str(e))) -+ -+ # test not a number -+ my_agmt = copy.deepcopy(agmt_dict) -+ my_agmt[attr] = notnum -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, my_agmt))) -+ log.fatal("Incorrectly allowed to add agreement entry with {}:{}".format(attr, notnum)) -+ assert False -+ except ldap.LDAPError as e: -+ log.info("Correctly failed to add agreement entry with {}:{} error: {}".format(attr, notnum, str(e))) -+ -+ # Test valid value -+ my_agmt = copy.deepcopy(agmt_dict) -+ my_agmt[attr] = valid -+ try: -+ topo.standalone.add_s(Entry((AGMT_DN, my_agmt))) -+ log.info("Correctly allowed to add agreement entry with {}: {}".format(attr, valid)) -+ except ldap.LDAPError as e: -+ log.fatal("Incorrectly failed to add agreement entry with {}: {} error: {}".format(attr, valid, str(e))) -+ assert False -+ -+ -+@pytest.mark.parametrize("attr, too_small, too_big, overflow, notnum, valid", agmt_attrs) -+def test_agmt_num_modify(topo, attr, too_small, too_big, overflow, notnum, valid): -+ """Test all the number values you can set for a replica config entry -+ -+ :id: a8b47d4a-a089-4d70-8070-e6181209bf95 -+ :setup: standalone instance -+ :steps: -+ 1. Replace a value that is too small -+ 2. Replace a value that is too big -+ 3. Replace a value that overflows the int -+ 4. Replace a value with character value (not a number) -+ 5. Replace a vlue with a valid value -+ :expectedresults: -+ 1. Value is rejected -+ 2. Value is rejected -+ 3. Value is rejected -+ 4. Value is rejected -+ 5. Value is allowed -+ """ -+ -+ # Value too small -+ agmt_setup(topo) -+ try: -+ topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, too_small)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_small)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_small)) -+ -+ # Value too big -+ agmt_setup(topo) -+ try: -+ topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, too_big)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, too_big)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, too_big)) -+ -+ # Value overflow -+ agmt_setup(topo) -+ try: -+ topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, overflow)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, overflow)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, overflow)) -+ -+ # Value not a number -+ agmt_setup(topo) -+ try: -+ topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, notnum)]) -+ log.fatal('Invalid value for {}:{} was incorrectly allowed'.format(attr, notnum)) -+ assert False -+ except: -+ log.info('Invalid value for {}:{} was correctly rejected'.format(attr, notnum)) -+ -+ # Value is valid -+ agmt_setup(topo) -+ try: -+ topo.standalone.modify_s(AGMT_DN, [(ldap.MOD_REPLACE, attr, valid)]) -+ except ldap.LDAPError as e: -+ log.fatal('Valid value for {}:{} was incorrectly rejected. Error {}'.format(attr, valid, str(e))) -+ assert False -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif -index 246495214..ab124c86c 100644 ---- a/ldap/schema/01core389.ldif -+++ b/ldap/schema/01core389.ldif -@@ -303,6 +303,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2331 NAME 'nsslapd-logging-hr-timestamps - attributeTypes: ( 2.16.840.1.113730.3.1.2332 NAME 'allowWeakDHParam' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2333 NAME 'nsds5ReplicaReleaseTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2335 NAME 'nsds5ReplicaIgnoreMissingChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) -+attributeTypes: ( 2.16.840.1.113730.3.1.2336 NAME 'nsDS5ReplicaBindDnGroupCheckInterval' DESC 'Replication configuration setting for controlling the bind dn group check interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - # - # objectclasses - # -@@ -312,7 +313,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.44 NAME 'nsIndex' DESC 'Netscape defined - objectClasses: ( 2.16.840.1.113730.3.2.109 NAME 'nsBackendInstance' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) --objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout ) X-ORIGIN 'Netscape Directory Server' ) -+objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Replication configuration objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout $ nsDS5ReplicaBindDnGroupCheckInterval ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nstombstonecsn $ nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaFlowControlWindow $ nsds5ReplicaFlowControlPause $ nsDS5ReplicaWaitForAsyncResults $ nsds5ReplicaIgnoreMissingChange) X-ORIGIN 'Netscape Directory Server' ) - objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) -diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h -index 3bd878d4d..c6e79b7e2 100644 ---- a/ldap/servers/plugins/replication/repl5.h -+++ b/ldap/servers/plugins/replication/repl5.h -@@ -330,8 +330,8 @@ void replsupplier_configure(Repl_Supplier *rs, Slapi_PBlock *pb); - void replsupplier_start(Repl_Supplier *rs); - void replsupplier_stop(Repl_Supplier *rs); - void replsupplier_destroy(Repl_Supplier **rs); --void replsupplier_notify(Repl_Supplier *rs, PRUint32 eventmask); --PRUint32 replsupplier_get_status(Repl_Supplier *rs); -+void replsupplier_notify(Repl_Supplier *rs, uint32_t eventmask); -+uint32_t replsupplier_get_status(Repl_Supplier *rs); - - /* In repl5_plugins.c */ - int multimaster_set_local_purl(void); -@@ -383,7 +383,7 @@ int agmt_stop(Repl_Agmt *ra); - int agmt_replicate_now(Repl_Agmt *ra); - char *agmt_get_hostname(const Repl_Agmt *ra); - int agmt_get_port(const Repl_Agmt *ra); --PRUint32 agmt_get_transport_flags(const Repl_Agmt *ra); -+uint32_t agmt_get_transport_flags(const Repl_Agmt *ra); - char *agmt_get_binddn(const Repl_Agmt *ra); - struct berval *agmt_get_credentials(const Repl_Agmt *ra); - int agmt_get_bindmethod(const Repl_Agmt *ra); -@@ -448,8 +448,8 @@ int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e); - int agmt_set_timeout(Repl_Agmt *ra, long timeout); - int agmt_set_ignoremissing(Repl_Agmt *ra, long ignoremissing); - void agmt_update_done(Repl_Agmt *ra, int is_total); --PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt); --void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout); -+uint64_t agmt_get_protocol_timeout(Repl_Agmt *agmt); -+void agmt_set_protocol_timeout(Repl_Agmt *agmt, uint64_t timeout); - void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn); - void add_agmt_maxcsns(Slapi_Entry *e, Replica *r); - void agmt_remove_maxcsn(Repl_Agmt *ra); -@@ -532,8 +532,8 @@ void *consumer_connection_extension_constructor(void *object, void *parent); - void consumer_connection_extension_destructor(void *ext, void *object, void *parent); - - /* extension helpers for managing exclusive access */ --consumer_connection_extension *consumer_connection_extension_acquire_exclusive_access(void *conn, PRUint64 connid, int opid); --int consumer_connection_extension_relinquish_exclusive_access(void *conn, PRUint64 connid, int opid, PRBool force); -+consumer_connection_extension *consumer_connection_extension_acquire_exclusive_access(void *conn, uint64_t connid, int opid); -+int consumer_connection_extension_relinquish_exclusive_access(void *conn, uint64_t connid, int opid, PRBool force); - - /* mapping tree extension - stores replica object */ - typedef struct multimaster_mtnode_extension -@@ -666,8 +666,8 @@ Replica *replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_o - void replica_destroy(void **arg); - int replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid); - int replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid); --PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opid, const char *locking_purl, char **current_purl); --void replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid); -+PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, uint64_t connid, int opid, const char *locking_purl, char **current_purl); -+void replica_relinquish_exclusive_access(Replica *r, uint64_t 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); -@@ -685,11 +685,13 @@ PRBool replica_is_updatedn(Replica *r, const Slapi_DN *sdn); - void replica_set_updatedn(Replica *r, const Slapi_ValueSet *vs, int mod_op); - void replica_set_groupdn(Replica *r, const Slapi_ValueSet *vs, int mod_op); - char *replica_get_generation(const Replica *r); -+ - /* currently supported flags */ - #define REPLICA_LOG_CHANGES 0x1 /* enable change logging */ --PRBool replica_is_flag_set(const Replica *r, PRUint32 flag); --void replica_set_flag(Replica *r, PRUint32 flag, PRBool clear); --void replica_replace_flags(Replica *r, PRUint32 flags); -+ -+PRBool replica_is_flag_set(const Replica *r, uint32_t flag); -+void replica_set_flag(Replica *r, uint32_t flag, PRBool clear); -+void replica_replace_flags(Replica *r, uint32_t flags); - void replica_dump(Replica *r); - void replica_set_enabled(Replica *r, PRBool enable); - Object *replica_get_replica_from_dn(const Slapi_DN *dn); -@@ -720,7 +722,7 @@ int replica_delete_by_dn(const char *dn); - int replica_is_being_configured(const char *dn); - void consumer5_set_mapping_tree_state_for_replica(const Replica *r, RUV *supplierRuv); - Object *replica_get_for_backend(const char *be_name); --void replica_set_purge_delay(Replica *r, PRUint32 purge_delay); -+void replica_set_purge_delay(Replica *r, uint32_t purge_delay); - void replica_set_tombstone_reap_interval(Replica *r, long interval); - void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv); - void replica_set_ruv_dirty(Replica *r); -@@ -730,20 +732,20 @@ char *replica_get_dn(Replica *r); - void replica_check_for_tasks(Replica *r, Slapi_Entry *e); - void replica_update_state(time_t when, void *arg); - void replica_reset_csn_pl(Replica *r); --PRUint64 replica_get_protocol_timeout(Replica *r); --void replica_set_protocol_timeout(Replica *r, PRUint64 timeout); --PRUint64 replica_get_release_timeout(Replica *r); --void replica_set_release_timeout(Replica *r, PRUint64 timeout); -+uint64_t replica_get_protocol_timeout(Replica *r); -+void replica_set_protocol_timeout(Replica *r, uint64_t timeout); -+uint64_t replica_get_release_timeout(Replica *r); -+void replica_set_release_timeout(Replica *r, uint64_t timeout); - void replica_set_groupdn_checkinterval(Replica *r, int timeout); --PRUint64 replica_get_backoff_min(Replica *r); --PRUint64 replica_get_backoff_max(Replica *r); --void replica_set_backoff_min(Replica *r, PRUint64 min); --void replica_set_backoff_max(Replica *r, PRUint64 max); -+uint64_t replica_get_backoff_min(Replica *r); -+uint64_t replica_get_backoff_max(Replica *r); -+void replica_set_backoff_min(Replica *r, uint64_t min); -+void replica_set_backoff_max(Replica *r, uint64_t max); - int replica_get_agmt_count(Replica *r); - void replica_incr_agmt_count(Replica *r); - void replica_decr_agmt_count(Replica *r); --PRUint64 replica_get_precise_purging(Replica *r); --void replica_set_precise_purging(Replica *r, PRUint64 on_off); -+uint64_t replica_get_precise_purging(Replica *r); -+void replica_set_precise_purging(Replica *r, uint64_t 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); -@@ -764,8 +766,8 @@ void replica_unlock_replica(Replica *r); - is active, RECV should back off. And vice versa. But SEND can coexist. */ - #define REPLICA_TOTAL_EXCL_RECV 32 /* ditto */ - --PRBool replica_is_state_flag_set(Replica *r, PRInt32 flag); --void replica_set_state_flag(Replica *r, PRUint32 flag, PRBool clear); -+PRBool replica_is_state_flag_set(Replica *r, int32_t flag); -+void replica_set_state_flag(Replica *r, uint32_t flag, PRBool clear); - void replica_set_tombstone_reap_stop(Replica *r, PRBool val); - void replica_enable_replication(Replica *r); - void replica_disable_replication(Replica *r, Object *r_obj); -@@ -836,6 +838,8 @@ LDAPControl *create_managedsait_control(void); - LDAPControl *create_backend_control(Slapi_DN *sdn); - void repl_set_mtn_state_and_referrals(const Slapi_DN *sdn, const char *mtn_state, const RUV *ruv, char **ruv_referrals, char **other_referrals); - void repl_set_repl_plugin_path(const char *path); -+int repl_config_valid_num(const char *config_attr, char *config_attr_value, int64_t min, int64_t max, -+ int *returncode, char *errortext, int64_t *retval); - - /* repl5_updatedn_list.c */ - typedef void *ReplicaUpdateDNList; -diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c -index e2ab320e4..78fb91ae6 100644 ---- a/ldap/servers/plugins/replication/repl5_agmt.c -+++ b/ldap/servers/plugins/replication/repl5_agmt.c -@@ -65,31 +65,31 @@ - struct changecounter - { - ReplicaId rid; -- PRUint32 num_replayed; -- PRUint32 num_skipped; -+ uint32_t num_replayed; -+ uint32_t num_skipped; - }; - - typedef struct repl5agmt - { - char *hostname; /* remote hostname */ -- int port; /* port of remote server */ -- PRUint32 transport_flags; /* SSL, TLS, etc. */ -+ int64_t port; /* port of remote server */ -+ uint32_t transport_flags; /* SSL, TLS, etc. */ - char *binddn; /* DN to bind as */ - struct berval *creds; /* Password, or certificate */ -- int bindmethod; /* Bind method - simple, SSL */ -+ int64_t bindmethod; /* Bind method - simple, SSL */ - Slapi_DN *replarea; /* DN of replicated area */ - char **frac_attrs; /* list of fractional attributes to be replicated */ - char **frac_attrs_total; /* list of fractional attributes to be replicated for total update protocol */ - PRBool frac_attr_total_defined; /* TRUE if frac_attrs_total is defined */ - Schedule *schedule; /* Scheduling information */ -- int auto_initialize; /* 1 = automatically re-initialize replica */ -+ int64_t auto_initialize; /* 1 = automatically re-initialize replica */ - const Slapi_DN *dn; /* DN of replication agreement entry */ - const Slapi_RDN *rdn; /* RDN of replication agreement entry */ - char *long_name; /* Long name (rdn + host, port) of entry, for logging */ - Repl_Protocol *protocol; /* Protocol object - manages protocol */ - struct changecounter **changecounters; /* changes sent/skipped since server start up */ -- int num_changecounters; -- int max_changecounters; -+ int64_t num_changecounters; -+ int64_t max_changecounters; - time_t last_update_start_time; /* Local start time of last update session */ - time_t last_update_end_time; /* Local end time of last update session */ - char last_update_status[STATUS_LEN]; /* Status of last update. Format = numeric code textual description */ -@@ -102,35 +102,35 @@ typedef struct repl5agmt - Object *consumerRUV; /* last RUV received from the consumer - used for changelog purging */ - CSN *consumerSchemaCSN; /* last schema CSN received from the consumer */ - ReplicaId consumerRID; /* indicates if the consumer is the originator of a CSN */ -- int tmpConsumerRID; /* Indicates the consumer rid was set from the agmt maxcsn - it should be refreshed */ -- long timeout; /* timeout (in seconds) for outbound LDAP connections to remote server */ -+ int64_t tmpConsumerRID; /* Indicates the consumer rid was set from the agmt maxcsn - it should be refreshed */ -+ int64_t timeout; /* timeout (in seconds) for outbound LDAP connections to remote server */ - PRBool stop_in_progress; /* set by agmt_stop when shutting down */ -- long busywaittime; /* time in seconds to wait after getting a REPLICA BUSY from the consumer - -- to allow another supplier to finish sending its updates - -- if set to 0, this means to use the default value if we get a busy -- signal from the consumer */ -- long pausetime; /* time in seconds to pause after sending updates - -- to allow another supplier to send its updates - -- should be greater than busywaittime - -- if set to 0, this means do not pause */ -+ int64_t busywaittime; /* time in seconds to wait after getting a REPLICA BUSY from the consumer - -+ * to allow another supplier to finish sending its updates - -+ * if set to 0, this means to use the default value if we get a busy -+ * signal from the consumer -+ */ -+ int64_t pausetime; /* time in seconds to pause after sending updates - -+ * to allow another supplier to send its updates - -+ * should be greater than busywaittime - -+ * if set to 0, this means do not pause -+ */ - void *priv; /* private data, used for windows-specific agreement data -- for sync agreements or for replication session plug-in -- private data for normal replication agreements */ -+ * for sync agreements or for replication session plug-in -+ * private data for normal replication agreements -+ */ - char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes: -- * modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */ -- int agreement_type; -+ * modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */ -+ int64_t agreement_type; - Slapi_Counter *protocol_timeout; -- char *maxcsn; /* agmt max csn */ -- long flowControlWindow; /* This is the maximum number of entries -- * sent without acknowledgment -- */ -- long flowControlPause; /* When nb of not acknowledged entries overpass totalUpdateWindow -- * This is the duration (in msec) that the RA will pause before sending the next entry -- */ -- long ignoreMissingChange; /* if set replication will try to continue even if change cannot be found in changelog */ -- Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */ -- int WaitForAsyncResults; /* Pass to DS_Sleep(PR_MillisecondsToInterval(WaitForAsyncResults)) -- * in repl5_inc_waitfor_async_results */ -+ char *maxcsn; /* agmt max csn */ -+ int64_t flowControlWindow; /* This is the maximum number of entries sent without acknowledgment */ -+ int64_t flowControlPause; /* When nb of not acknowledged entries overpass totalUpdateWindow -+ * This is the duration (in msec) that the RA will pause before sending the next entry */ -+ int64_t ignoreMissingChange; /* if set replication will try to continue even if change cannot be found in changelog */ -+ Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */ -+ int64_t WaitForAsyncResults; /* Pass to DS_Sleep(PR_MillisecondsToInterval(WaitForAsyncResults)) -+ * in repl5_inc_waitfor_async_results */ - } repl5agmt; - - /* Forward declarations */ -@@ -182,7 +182,7 @@ agmt_is_valid(Repl_Agmt *ra) - } - if (ra->port <= 0) { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "agmt_is_valid - Replication agreement \"%s\" " -- "is malformed: invalid port number %d.\n", -+ "is malformed: invalid port number %ld.\n", - slapi_sdn_get_dn(ra->dn), ra->port); - return_value = 0; - } -@@ -241,10 +241,14 @@ agmt_new_from_entry(Slapi_Entry *e) - { - Repl_Agmt *ra; - Slapi_Attr *sattr; -+ char errormsg[SLAPI_DSE_RETURNTEXT_SIZE]; - char *tmpstr; - char **denied_attrs = NULL; - char *auto_initialize = NULL; - char *val_nsds5BeginReplicaRefresh = "start"; -+ char *val = NULL; -+ int64_t ptimeout = 0; -+ int rc = 0; - - ra = (Repl_Agmt *)slapi_ch_calloc(1, sizeof(repl5agmt)); - if ((ra->lock = PR_NewLock()) == NULL) { -@@ -283,8 +287,17 @@ agmt_new_from_entry(Slapi_Entry *e) - - /* Host name of remote replica */ - ra->hostname = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaHost); -+ - /* Port number for remote replica instance */ -- ra->port = slapi_entry_attr_get_int(e, type_nsds5ReplicaPort); -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaPort))){ -+ int64_t port; -+ if (repl_config_valid_num(type_nsds5ReplicaPort, val, 1, 65535, &rc, errormsg, &port) != 0) { -+ goto loser; -+ } -+ slapi_ch_free_string(&val); -+ ra->port = port; -+ } -+ - /* SSL, TLS, or other transport stuff */ - ra->transport_flags = 0; - (void)agmt_set_transportinfo_no_lock(ra, e); -@@ -313,29 +326,35 @@ agmt_new_from_entry(Slapi_Entry *e) - - /* timeout. */ - ra->timeout = DEFAULT_TIMEOUT; -- if (slapi_entry_attr_find(e, type_nsds5ReplicaTimeout, &sattr) == 0) { -- Slapi_Value *sval; -- if (slapi_attr_first_value(sattr, &sval) == 0) { -- ra->timeout = slapi_value_get_long(sval); -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaTimeout))){ -+ int64_t timeout; -+ if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &timeout) != 0) { -+ goto loser; - } -+ slapi_ch_free_string(&val); -+ ra->timeout = timeout; - } - - /* flow control update window. */ - ra->flowControlWindow = DEFAULT_FLOWCONTROL_WINDOW; -- if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlWindow, &sattr) == 0) { -- Slapi_Value *sval; -- if (slapi_attr_first_value(sattr, &sval) == 0) { -- ra->flowControlWindow = slapi_value_get_long(sval); -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlWindow))){ -+ int64_t flow; -+ if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) { -+ goto loser; - } -+ slapi_ch_free_string(&val); -+ ra->flowControlWindow = flow; - } - - /* flow control update pause. */ - ra->flowControlPause = DEFAULT_FLOWCONTROL_PAUSE; -- if (slapi_entry_attr_find(e, type_nsds5ReplicaFlowControlPause, &sattr) == 0) { -- Slapi_Value *sval; -- if (slapi_attr_first_value(sattr, &sval) == 0) { -- ra->flowControlPause = slapi_value_get_long(sval); -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlPause))){ -+ int64_t pause; -+ if (repl_config_valid_num(type_nsds5ReplicaFlowControlPause, val, 0, INT_MAX, &rc, errormsg, &pause) != 0) { -+ goto loser; - } -+ slapi_ch_free_string(&val); -+ ra->flowControlPause = pause; - } - - /* continue on missing change ? */ -@@ -357,7 +376,6 @@ agmt_new_from_entry(Slapi_Entry *e) - if (NULL != tmpstr) { - Object *repl_obj; - Replica *replica; -- PRUint64 ptimeout = 0; - - ra->replarea = slapi_sdn_new_dn_passin(tmpstr); - -@@ -367,14 +385,18 @@ agmt_new_from_entry(Slapi_Entry *e) - replica_incr_agmt_count(replica); - } - } -+ } - -- /* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */ -- ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout); -- if (ptimeout) { -- slapi_counter_set_value(ra->protocol_timeout, ptimeout); -+ /* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */ -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaProtocolTimeout))){ -+ if (repl_config_valid_num(type_replicaProtocolTimeout, val, 0, INT_MAX, &rc, errormsg, &ptimeout) != 0) { -+ goto loser; - } -+ slapi_ch_free_string(&val); -+ slapi_counter_set_value(ra->protocol_timeout, ptimeout); - } - -+ - /* Replica enabled */ - tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaEnabled); - if (NULL != tmpstr) { -@@ -384,9 +406,8 @@ agmt_new_from_entry(Slapi_Entry *e) - ra->is_enabled = PR_TRUE; - } else { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "agmt_new_from_entry - " -- "Warning invalid value for nsds5ReplicaEnabled (%s), value must be \"on\" or \"off\". " -- "Ignoring this repl agreement.\n", -- tmpstr); -+ "Warning invalid value for nsds5ReplicaEnabled (%s), value must be \"on\" or \"off\". " -+ "Ignoring this repl agreement.\n", tmpstr); - slapi_ch_free_string(&tmpstr); - goto loser; - } -@@ -402,11 +423,24 @@ agmt_new_from_entry(Slapi_Entry *e) - } - - /* busy wait time - time to wait after getting REPLICA BUSY from consumer */ -- ra->busywaittime = slapi_entry_attr_get_long(e, type_nsds5ReplicaBusyWaitTime); -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaBusyWaitTime))){ -+ int64_t busytime = 0; -+ if (repl_config_valid_num(type_nsds5ReplicaBusyWaitTime, val, 0, INT_MAX, &rc, errormsg, &busytime) != 0) { -+ goto loser; -+ } -+ slapi_ch_free_string(&val); -+ ra->busywaittime = busytime; -+ } - - /* pause time - time to pause after a session has ended */ -- ra->pausetime = slapi_entry_attr_get_long(e, type_nsds5ReplicaSessionPauseTime); -- -+ if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaSessionPauseTime))){ -+ int64_t pausetime = 0; -+ if (repl_config_valid_num(type_nsds5ReplicaSessionPauseTime, val, 0, INT_MAX, &rc, errormsg, &pausetime) != 0) { -+ goto loser; -+ } -+ slapi_ch_free_string(&val); -+ ra->pausetime = pausetime; -+ } - /* consumer's RUV */ - if (slapi_entry_attr_find(e, type_ruvElement, &sattr) == 0) { - RUV *ruv; -@@ -434,7 +468,7 @@ agmt_new_from_entry(Slapi_Entry *e) - if (dot) { - *dot = '\0'; - } -- ra->long_name = slapi_ch_smprintf("agmt=\"%s\" (%s:%d)", agmtname, hostname, ra->port); -+ ra->long_name = slapi_ch_smprintf("agmt=\"%s\" (%s:%ld)", agmtname, hostname, ra->port); - } - - /* DBDB: review this code */ -@@ -534,6 +568,9 @@ agmt_new_from_entry(Slapi_Entry *e) - - return ra; - loser: -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, -+ "agmt_new_from_entry - Failed to parse agreement, skipping.\n"); -+ slapi_ch_free_string(&val); - agmt_delete((void **)&ra); - return NULL; - } -@@ -754,10 +791,10 @@ agmt_start(Repl_Agmt *ra) - char buf[BUFSIZ]; - char unavail_buf[BUFSIZ]; - -- PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%d;", slapi_sdn_get_dn(repl_sdn), -+ PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%ld;", slapi_sdn_get_dn(repl_sdn), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), - ra->hostname, ra->port); -- PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(repl_sdn), -+ PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%ld;unavailable", slapi_sdn_get_dn(repl_sdn), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), - ra->hostname, ra->port); - if (strstr(maxcsns[i], buf) || strstr(maxcsns[i], unavail_buf)) { -@@ -901,7 +938,7 @@ agmt_get_port(const Repl_Agmt *ra) - /* - * Return the transport flags for this agreement. - */ --PRUint32 -+uint32_t - agmt_get_transport_flags(const Repl_Agmt *ra) - { - unsigned int return_value; -@@ -2919,7 +2956,7 @@ agmt_update_done(Repl_Agmt *agmt, int is_total) - } - } - --PRUint64 -+uint64_t - agmt_get_protocol_timeout(Repl_Agmt *agmt) - { - if (agmt) { -@@ -2930,7 +2967,7 @@ agmt_get_protocol_timeout(Repl_Agmt *agmt) - } - - void --agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout) -+agmt_set_protocol_timeout(Repl_Agmt *agmt, uint64_t timeout) - { - if (agmt) { - slapi_counter_set_value(agmt->protocol_timeout, timeout); -@@ -2992,11 +3029,11 @@ agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn) - * temporarily mark it as "unavailable". - */ - slapi_ch_free_string(&agmt->maxcsn); -- agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%d;unavailable", slapi_sdn_get_dn(agmt->replarea), -+ agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%ld;unavailable", slapi_sdn_get_dn(agmt->replarea), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(agmt->rdn)), agmt->hostname, agmt->port); - } else if (rid == oprid) { - slapi_ch_free_string(&agmt->maxcsn); -- agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%d;%d;%s", slapi_sdn_get_dn(agmt->replarea), -+ agmt->maxcsn = slapi_ch_smprintf("%s;%s;%s;%ld;%d;%s", slapi_sdn_get_dn(agmt->replarea), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(agmt->rdn)), agmt->hostname, - agmt->port, agmt->consumerRID, maxcsn); - } -@@ -3190,10 +3227,10 @@ agmt_remove_maxcsn(Repl_Agmt *ra) - char unavail_buf[BUFSIZ]; - struct berval val; - -- PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%d;", slapi_sdn_get_dn(ra->replarea), -+ PR_snprintf(buf, BUFSIZ, "%s;%s;%s;%ld;", slapi_sdn_get_dn(ra->replarea), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), - ra->hostname, ra->port); -- PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%d;unavailable", -+ PR_snprintf(unavail_buf, BUFSIZ, "%s;%s;%s;%ld;unavailable", - slapi_sdn_get_dn(ra->replarea), - slapi_rdn_get_value_by_ref(slapi_rdn_get_rdn(ra->rdn)), - ra->hostname, ra->port); -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index 92f847f24..e5296bf1c 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -33,42 +33,40 @@ struct replica - Slapi_DN *repl_root; /* top of the replicated are */ - char *repl_name; /* unique replica name */ - PRBool new_name; /* new name was generated - need to be saved */ -- ReplicaUpdateDNList updatedn_list; /* list of dns with which a supplier should bind -- to update this replica */ -- Slapi_ValueSet *updatedn_groups; /* set of groups whose memebers are -- * allowed to update replica */ -+ ReplicaUpdateDNList updatedn_list; /* list of dns with which a supplier should bind to update this replica */ -+ Slapi_ValueSet *updatedn_groups; /* set of groups whose memebers are allowed to update replica */ - ReplicaUpdateDNList groupdn_list; /* exploded listof dns from update group */ -- PRUint32 updatedn_group_last_check; -- int updatedn_group_check_interval; -- ReplicaType repl_type; /* is this replica read-only ? */ -- ReplicaId repl_rid; /* replicaID */ -- Object *repl_ruv; /* replica update vector */ -- PRBool repl_ruv_dirty; /* Dirty flag for ruv */ -- CSNPL *min_csn_pl; /* Pending list for minimal CSN */ -- void *csn_pl_reg_id; /* registration assignment for csn callbacks */ -- unsigned long repl_state_flags; /* state flags */ -- PRUint32 repl_flags; /* persistent, externally visible flags */ -- PRMonitor *repl_lock; /* protects entire structure */ -- Slapi_Eq_Context repl_eqcxt_rs; /* context to cancel event that saves ruv */ -- Slapi_Eq_Context repl_eqcxt_tr; /* context to cancel event that reaps tombstones */ -- Object *repl_csngen; /* CSN generator for this replica */ -- PRBool repl_csn_assigned; /* Flag set when new csn is assigned. */ -- PRUint32 repl_purge_delay; /* When purgeable, CSNs are held on to for this many extra seconds */ -- PRBool tombstone_reap_stop; /* TRUE when the tombstone reaper should stop */ -- PRBool tombstone_reap_active; /* TRUE when the tombstone reaper is running */ -- long tombstone_reap_interval; /* Time in seconds between tombstone reaping */ -- Slapi_ValueSet *repl_referral; /* A list of administrator provided referral URLs */ -- 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 */ -- Slapi_Counter *precise_purging; /* Enable precise tombstone purging */ -- PRUint64 agmt_count; /* Number of agmts */ -- Slapi_Counter *release_timeout; /* The amount of time to wait before releasing active replica */ -- PRUint64 abort_session; /* Abort the current replica session */ -+ uint32_t updatedn_group_last_check; /* the time of the last group check */ -+ int64_t updatedn_group_check_interval; /* the group check interval */ -+ ReplicaType repl_type; /* is this replica read-only ? */ -+ ReplicaId repl_rid; /* replicaID */ -+ Object *repl_ruv; /* replica update vector */ -+ PRBool repl_ruv_dirty; /* Dirty flag for ruv */ -+ CSNPL *min_csn_pl; /* Pending list for minimal CSN */ -+ void *csn_pl_reg_id; /* registration assignment for csn callbacks */ -+ unsigned long repl_state_flags; /* state flags */ -+ uint32_t repl_flags; /* persistent, externally visible flags */ -+ PRMonitor *repl_lock; /* protects entire structure */ -+ Slapi_Eq_Context repl_eqcxt_rs; /* context to cancel event that saves ruv */ -+ Slapi_Eq_Context repl_eqcxt_tr; /* context to cancel event that reaps tombstones */ -+ Object *repl_csngen; /* CSN generator for this replica */ -+ PRBool repl_csn_assigned; /* Flag set when new csn is assigned. */ -+ int64_t repl_purge_delay; /* When purgeable, CSNs are held on to for this many extra seconds */ -+ PRBool tombstone_reap_stop; /* TRUE when the tombstone reaper should stop */ -+ PRBool tombstone_reap_active; /* TRUE when the tombstone reaper is running */ -+ int64_t tombstone_reap_interval; /* Time in seconds between tombstone reaping */ -+ Slapi_ValueSet *repl_referral; /* A list of administrator provided referral URLs */ -+ 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 */ -+ Slapi_Counter *precise_purging; /* Enable precise tombstone purging */ -+ uint64_t agmt_count; /* Number of agmts */ -+ Slapi_Counter *release_timeout; /* The amount of time to wait before releasing active replica */ -+ uint64_t abort_session; /* Abort the current replica session */ - }; - - -@@ -532,7 +530,7 @@ replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid) - * current_purl is the supplier who already has access, if any - */ - PRBool --replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opid, const char *locking_purl, char **current_purl) -+replica_get_exclusive_access(Replica *r, PRBool *isInc, uint64_t connid, int opid, const char *locking_purl, char **current_purl) - { - PRBool rval = PR_TRUE; - -@@ -608,7 +606,7 @@ done: - * Relinquish exclusive access to the replica - */ - void --replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid) -+replica_relinquish_exclusive_access(Replica *r, uint64_t connid, int opid) - { - PRBool isInc; - -@@ -915,7 +913,7 @@ replica_get_type(const Replica *r) - return r->repl_type; - } - --PRUint64 -+uint64_t - replica_get_protocol_timeout(Replica *r) - { - if (r) { -@@ -925,7 +923,7 @@ replica_get_protocol_timeout(Replica *r) - } - } - --PRUint64 -+uint64_t - replica_get_release_timeout(Replica *r) - { - if (r) { -@@ -936,7 +934,7 @@ replica_get_release_timeout(Replica *r) - } - - void --replica_set_release_timeout(Replica *r, PRUint64 limit) -+replica_set_release_timeout(Replica *r, uint64_t limit) - { - if (r) { - slapi_counter_set_value(r->release_timeout, limit); -@@ -944,7 +942,7 @@ replica_set_release_timeout(Replica *r, PRUint64 limit) - } - - void --replica_set_protocol_timeout(Replica *r, PRUint64 timeout) -+replica_set_protocol_timeout(Replica *r, uint64_t timeout) - { - if (r) { - slapi_counter_set_value(r->protocol_timeout, timeout); -@@ -1182,7 +1180,7 @@ replica_get_generation(const Replica *r) - } - - PRBool --replica_is_flag_set(const Replica *r, PRUint32 flag) -+replica_is_flag_set(const Replica *r, uint32_t flag) - { - if (r) - return (r->repl_flags & flag); -@@ -1191,7 +1189,7 @@ replica_is_flag_set(const Replica *r, PRUint32 flag) - } - - void --replica_set_flag(Replica *r, PRUint32 flag, PRBool clear) -+replica_set_flag(Replica *r, uint32_t flag, PRBool clear) - { - if (r == NULL) - return; -@@ -1208,7 +1206,7 @@ replica_set_flag(Replica *r, PRUint32 flag, PRBool clear) - } - - void --replica_replace_flags(Replica *r, PRUint32 flags) -+replica_replace_flags(Replica *r, uint32_t flags) - { - if (r) { - replica_lock(r->repl_lock); -@@ -1829,17 +1827,18 @@ _replica_check_validity(const Replica *r) - static int - _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - { -- Slapi_Attr *a = NULL; - Slapi_Attr *attr; - CSNGen *gen; - char *precise_purging = NULL; - char buf[SLAPI_DSE_RETURNTEXT_SIZE]; - char *errormsg = errortext ? errortext : buf; - char *val; -- int backoff_min; -- int backoff_max; -- int ptimeout = 0; -- int release_timeout = 0; -+ int64_t backoff_min; -+ int64_t backoff_max; -+ int64_t ptimeout = 0; -+ int64_t release_timeout = 0; -+ int64_t interval = 0; -+ int64_t rtype = 0; - int rc; - - PR_ASSERT(r && e); -@@ -1847,7 +1846,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - /* get replica root */ - val = slapi_entry_attr_get_charptr(e, attr_replicaRoot); - if (val == NULL) { -- PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to retrieve %s attribute from (%s)\n", -+ PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to retrieve %s attribute from (%s)", - attr_replicaRoot, - (char *)slapi_entry_get_dn((Slapi_Entry *)e)); - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - %s\n", -@@ -1858,66 +1857,94 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - r->repl_root = slapi_sdn_new_dn_passin(val); - - /* get replica type */ -- val = slapi_entry_attr_get_charptr(e, attr_replicaType); -- if (val) { -- r->repl_type = atoi(val); -- slapi_ch_free((void **)&val); -+ if (slapi_entry_attr_exists(e, attr_replicaType)) { -+ if ((val = slapi_entry_attr_get_charptr(e, attr_replicaType))) { -+ if (repl_config_valid_num(attr_replicaType, val, 0, REPLICA_TYPE_UPDATABLE, &rc, errormsg, &rtype) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ r->repl_type = rtype; -+ slapi_ch_free_string(&val); -+ } else { -+ r->repl_type = REPLICA_TYPE_READONLY; -+ } - } else { - r->repl_type = REPLICA_TYPE_READONLY; - } - -- /* grab and validate the backoff retry settings */ -+ /* grab and validate the backoff min retry settings */ - if (slapi_entry_attr_exists(e, type_replicaBackoffMin)) { -- backoff_min = slapi_entry_attr_get_int(e, type_replicaBackoffMin); -- if (backoff_min <= 0) { -- slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - " -- "Invalid value for %s: %d Using default value (%d)\n", -- type_replicaBackoffMin, backoff_min, PROTOCOL_BACKOFF_MINIMUM); -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMin))) { -+ if (repl_config_valid_num(type_replicaBackoffMin, val, 1, INT_MAX, &rc, errormsg, &backoff_min) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ slapi_ch_free_string(&val); -+ } else { - backoff_min = PROTOCOL_BACKOFF_MINIMUM; - } - } else { - backoff_min = PROTOCOL_BACKOFF_MINIMUM; - } - -+ /* grab and validate the backoff max retry settings */ - if (slapi_entry_attr_exists(e, type_replicaBackoffMax)) { -- backoff_max = slapi_entry_attr_get_int(e, type_replicaBackoffMax); -- if (backoff_max <= 0) { -- slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - " -- "Invalid value for %s: %d Using default value (%d)\n", -- type_replicaBackoffMax, backoff_max, PROTOCOL_BACKOFF_MAXIMUM); -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaBackoffMax))) { -+ if (repl_config_valid_num(type_replicaBackoffMax, val, 1, INT_MAX, &rc, errormsg, &backoff_max) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ slapi_ch_free_string(&val); -+ } else { - backoff_max = PROTOCOL_BACKOFF_MAXIMUM; - } - } else { - backoff_max = PROTOCOL_BACKOFF_MAXIMUM; - } - -+ /* Verify backoff min and max work together */ - if (backoff_min > backoff_max) { -- /* Ok these values are invalid, reset back the defaults */ -- slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - " -- "Backoff minimum (%d) can not be greater than " -- "the backoff maximum (%d). Using default values: min (%d) max (%d)\n", -- backoff_min, backoff_max, PROTOCOL_BACKOFF_MINIMUM, PROTOCOL_BACKOFF_MAXIMUM); -- slapi_counter_set_value(r->backoff_min, PROTOCOL_BACKOFF_MINIMUM); -- slapi_counter_set_value(r->backoff_max, PROTOCOL_BACKOFF_MAXIMUM); -+ PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Backoff minimum (%ld) can not be greater than the backoff maximum (%ld).", -+ backoff_min, backoff_max); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - " -+ "%s\n", errormsg); -+ return -1; - } else { - slapi_counter_set_value(r->backoff_min, backoff_min); - slapi_counter_set_value(r->backoff_max, backoff_max); - } - - /* get the protocol timeout */ -- ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout); -- if (ptimeout <= 0) { -- slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT); -+ if (slapi_entry_attr_exists(e, type_replicaProtocolTimeout)) { -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaProtocolTimeout))) { -+ if (repl_config_valid_num(type_replicaProtocolTimeout, val, 0, INT_MAX, &rc, errormsg, &ptimeout) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ slapi_ch_free_string(&val); -+ slapi_counter_set_value(r->protocol_timeout, ptimeout); -+ } else { -+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT); -+ } - } else { -- slapi_counter_set_value(r->protocol_timeout, ptimeout); -+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT); - } - - /* Get the release timeout */ -- release_timeout = slapi_entry_attr_get_int(e, type_replicaReleaseTimeout); -- if (release_timeout <= 0) { -- slapi_counter_set_value(r->release_timeout, 0); -+ if (slapi_entry_attr_exists(e, type_replicaReleaseTimeout)) { -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaReleaseTimeout))) { -+ if (repl_config_valid_num(type_replicaReleaseTimeout, val, 0, INT_MAX, &rc, errortext, &release_timeout) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ slapi_counter_set_value(r->release_timeout, release_timeout); -+ slapi_ch_free_string(&val); -+ } else { -+ slapi_counter_set_value(r->release_timeout, 0); -+ } - } else { -- slapi_counter_set_value(r->release_timeout, release_timeout); -+ slapi_counter_set_value(r->release_timeout, 0); - } - - /* check for precise tombstone purging */ -@@ -1929,10 +1956,11 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - slapi_counter_set_value(r->precise_purging, 0); - } else { - /* Invalid value */ -- slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "_replica_init_from_config - " -- "Invalid value for %s: %s Using default value (off)\n", -- type_replicaPrecisePurge, precise_purging); -- slapi_counter_set_value(r->precise_purging, 0); -+ PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for %s: %s", -+ type_replicaPrecisePurge, precise_purging); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "_replica_init_from_config - " -+ "%s\n", errormsg); -+ return -1; - } - slapi_ch_free_string(&precise_purging); - } else { -@@ -1940,7 +1968,19 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - } - - /* get replica flags */ -- r->repl_flags = slapi_entry_attr_get_ulong(e, attr_flags); -+ if (slapi_entry_attr_exists(e, attr_flags)) { -+ int64_t rflags; -+ if((val = slapi_entry_attr_get_charptr(e, attr_flags))) { -+ if (repl_config_valid_num(attr_flags, val, 0, 1, &rc, errortext, &rflags) != 0) { -+ return -1; -+ } -+ r->repl_flags = (uint32_t)rflags; -+ } else { -+ r->repl_flags = 0; -+ } -+ } else { -+ r->repl_flags = 0; -+ } - - /* - * Get replicaid -@@ -1955,20 +1995,13 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - else if (r->repl_type == REPLICA_TYPE_UPDATABLE || - r->repl_type == REPLICA_TYPE_PRIMARY) { - if ((val = slapi_entry_attr_get_charptr(e, attr_replicaId))) { -- int temprid = atoi(val); -- slapi_ch_free((void **)&val); -- if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID) { -- PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s must have a value greater than 0 " -- "and less than %d: entry %s", -- attr_replicaId, READ_ONLY_REPLICA_ID, -- (char *)slapi_entry_get_dn((Slapi_Entry *)e)); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, -- "_replica_init_from_config - %s\n", errormsg); -+ int64_t rid; -+ if (repl_config_valid_num(attr_replicaId, val, 1, 65535, &rc, errormsg, &rid) != 0) { -+ slapi_ch_free_string(&val); - return -1; -- } else { -- r->repl_rid = (ReplicaId)temprid; - } -+ r->repl_rid = (ReplicaId)rid; -+ slapi_ch_free_string(&val); - } else { - PR_snprintf(errormsg, SLAPI_DSE_RETURNTEXT_SIZE, - "Failed to retrieve required %s attribute from %s", -@@ -2003,10 +2036,13 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - r->groupdn_list = replica_groupdn_list_new(r->updatedn_groups); - r->updatedn_group_last_check = time(NULL); - /* get groupdn check interval */ -- val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval); -- if (val) { -- r->updatedn_group_check_interval = atoi(val); -- slapi_ch_free((void **)&val); -+ if ((val = slapi_entry_attr_get_charptr(e, attr_replicaBindDnGroupCheckInterval))) { -+ if (repl_config_valid_num(attr_replicaBindDnGroupCheckInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ r->updatedn_group_check_interval = interval; -+ slapi_ch_free_string(&val); - } else { - r->updatedn_group_check_interval = -1; - } -@@ -2041,18 +2077,26 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - * since we don't know about LCUP replicas, and they can just - * turn up whenever they want to. - */ -- if (slapi_entry_attr_find(e, type_replicaPurgeDelay, &a) == -1) { -- /* No purge delay provided, so use default */ -- r->repl_purge_delay = 60 * 60 * 24 * 7; /* One week, in seconds */ -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaPurgeDelay))) { -+ if (repl_config_valid_num(type_replicaPurgeDelay, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ r->repl_purge_delay = interval; -+ slapi_ch_free_string(&val); - } else { -- r->repl_purge_delay = slapi_entry_attr_get_uint(e, type_replicaPurgeDelay); -+ r->repl_purge_delay = 60 * 60 * 24 * 7; /* One week, in seconds */ - } - -- if (slapi_entry_attr_find(e, type_replicaTombstonePurgeInterval, &a) == -1) { -- /* No reap interval provided, so use default */ -- r->tombstone_reap_interval = 3600 * 24; /* One day */ -+ if ((val = slapi_entry_attr_get_charptr(e, type_replicaTombstonePurgeInterval))) { -+ if (repl_config_valid_num(type_replicaTombstonePurgeInterval, val, -1, INT_MAX, &rc, errormsg, &interval) != 0) { -+ slapi_ch_free_string(&val); -+ return -1; -+ } -+ r->tombstone_reap_interval = interval; -+ slapi_ch_free_string(&val); - } else { -- r->tombstone_reap_interval = slapi_entry_attr_get_int(e, type_replicaTombstonePurgeInterval); -+ r->tombstone_reap_interval = 3600 * 24; /* One week, in seconds */ - } - - r->tombstone_reap_stop = r->tombstone_reap_active = PR_FALSE; -@@ -3534,7 +3578,7 @@ replica_log_ruv_elements_nolock(const Replica *r) - } - - void --replica_set_purge_delay(Replica *r, PRUint32 purge_delay) -+replica_set_purge_delay(Replica *r, uint32_t purge_delay) - { - PR_ASSERT(r); - replica_lock(r->repl_lock); -@@ -3710,7 +3754,7 @@ replica_set_ruv_dirty(Replica *r) - } - - PRBool --replica_is_state_flag_set(Replica *r, PRInt32 flag) -+replica_is_state_flag_set(Replica *r, int32_t flag) - { - PR_ASSERT(r); - if (r) -@@ -3720,7 +3764,7 @@ replica_is_state_flag_set(Replica *r, PRInt32 flag) - } - - void --replica_set_state_flag(Replica *r, PRUint32 flag, PRBool clear) -+replica_set_state_flag(Replica *r, uint32_t flag, PRBool clear) - { - if (r == NULL) - return; -@@ -3994,7 +4038,7 @@ replica_get_attr(Slapi_PBlock *pb, const char *type, void *value) - return rc; - } - --PRUint64 -+uint64_t - replica_get_backoff_min(Replica *r) - { - if (r) { -@@ -4004,7 +4048,7 @@ replica_get_backoff_min(Replica *r) - } - } - --PRUint64 -+uint64_t - replica_get_backoff_max(Replica *r) - { - if (r) { -@@ -4015,7 +4059,7 @@ replica_get_backoff_max(Replica *r) - } - - void --replica_set_backoff_min(Replica *r, PRUint64 min) -+replica_set_backoff_min(Replica *r, uint64_t min) - { - if (r) { - slapi_counter_set_value(r->backoff_min, min); -@@ -4023,7 +4067,7 @@ replica_set_backoff_min(Replica *r, PRUint64 min) - } - - void --replica_set_backoff_max(Replica *r, PRUint64 max) -+replica_set_backoff_max(Replica *r, uint64_t max) - { - if (r) { - slapi_counter_set_value(r->backoff_max, max); -@@ -4031,14 +4075,14 @@ replica_set_backoff_max(Replica *r, PRUint64 max) - } - - void --replica_set_precise_purging(Replica *r, PRUint64 on_off) -+replica_set_precise_purging(Replica *r, uint64_t on_off) - { - if (r) { - slapi_counter_set_value(r->precise_purging, on_off); - } - } - --PRUint64 -+uint64_t - replica_get_precise_purging(Replica *r) - { - if (r) { -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 7477a292c..9c3c75458 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -405,28 +405,35 @@ replica_config_modify(Slapi_PBlock *pb, - } else if (strcasecmp(config_attr, attr_replicaBindDnGroup) == 0) { - *returncode = replica_config_change_updatedngroup(r, mods[i], errortext, apply_mods); - } else if (strcasecmp(config_attr, attr_replicaBindDnGroupCheckInterval) == 0) { -- int interval = atoi(config_attr_value); -- replica_set_groupdn_checkinterval(r, interval); -+ int64_t interval = 0; -+ if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &interval) == 0) { -+ replica_set_groupdn_checkinterval(r, interval); -+ } else { -+ break; -+ } - } else if (strcasecmp(config_attr, attr_replicaType) == 0) { -+ int64_t rtype; - slapi_ch_free_string(&new_repl_type); -- new_repl_type = slapi_ch_strdup(config_attr_value); -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, 3, returncode, errortext, &rtype) == 0) { -+ new_repl_type = slapi_ch_strdup(config_attr_value); -+ } else { -+ break; -+ } - } else if (strcasecmp(config_attr, attr_replicaId) == 0) { -- char *endp = NULL; - int64_t rid = 0; -- errno = 0; -- rid = strtoll(config_attr_value, &endp, 10); -- if (*endp != '\0' || rid > 65535 || rid < 1 || errno == ERANGE) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number between 1 and 65535.\n", -- config_attr, config_attr_value); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, 65535, returncode, errortext, &rid) == 0) { -+ slapi_ch_free_string(&new_repl_id); -+ new_repl_id = slapi_ch_strdup(config_attr_value); -+ } else { - break; - } -- slapi_ch_free_string(&new_repl_id); -- new_repl_id = slapi_ch_strdup(config_attr_value); - } else if (strcasecmp(config_attr, attr_flags) == 0) { -- *returncode = replica_config_change_flags(r, config_attr_value, errortext, apply_mods); -+ int64_t rflags = 0; -+ if (repl_config_valid_num(config_attr, config_attr_value, 0, 1, returncode, errortext, &rflags) == 0) { -+ *returncode = replica_config_change_flags(r, config_attr_value, errortext, apply_mods); -+ } else { -+ break; -+ } - } else if (strcasecmp(config_attr, TASK_ATTR) == 0) { - *returncode = replica_execute_task(mtnode_ext->replica, config_attr_value, errortext, apply_mods); - } else if (strcasecmp(config_attr, attr_replicaReferral) == 0) { -@@ -442,18 +449,21 @@ replica_config_modify(Slapi_PBlock *pb, - } - } else if (strcasecmp(config_attr, type_replicaPurgeDelay) == 0) { - if (apply_mods && config_attr_value[0]) { -- PRUint32 delay; -- if (isdigit(config_attr_value[0])) { -- delay = (unsigned int)atoi(config_attr_value); -+ int64_t delay = 0; -+ if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &delay) == 0) { - replica_set_purge_delay(r, delay); -- } else -- *returncode = LDAP_OPERATIONS_ERROR; -+ } else { -+ break; -+ } - } - } else if (strcasecmp(config_attr, type_replicaTombstonePurgeInterval) == 0) { - if (apply_mods && config_attr_value[0]) { -- long interval; -- interval = atol(config_attr_value); -- replica_set_tombstone_reap_interval(r, interval); -+ int64_t interval; -+ if (repl_config_valid_num(config_attr, config_attr_value, -1, INT_MAX, returncode, errortext, &interval) == 0) { -+ replica_set_tombstone_reap_interval(r, interval); -+ } else { -+ break; -+ } - } - } - /* ignore modifiers attributes added by the server */ -@@ -461,73 +471,55 @@ replica_config_modify(Slapi_PBlock *pb, - *returncode = LDAP_SUCCESS; - } else if (strcasecmp(config_attr, type_replicaProtocolTimeout) == 0) { - if (apply_mods) { -- PRUint64 ptimeout = 0; -- -- ptimeout = atoll(config_attr_value); -- -- if (ptimeout <= 0) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number greater than zero.\n", -- config_attr, config_attr_value); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ int64_t ptimeout = 0; -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &ptimeout) == 0) { -+ replica_set_protocol_timeout(r, ptimeout); -+ } else { - break; - } -- replica_set_protocol_timeout(r, ptimeout); - } - } else if (strcasecmp(config_attr, type_replicaBackoffMin) == 0) { - if (apply_mods) { -- uint64_t val = atoll(config_attr_value); -- uint64_t max; -- -- if (val <= 0) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number greater than zero.\n", -- config_attr, config_attr_value); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -- break; -- } -- max = replica_get_backoff_max(r); -- if (val > max){ -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n", -- config_attr, config_attr_value, (int)max); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ int64_t val = 0; -+ int64_t max; -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) { -+ max = replica_get_backoff_max(r); -+ if (val > max){ -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number less than the max backoff time (%d).\n", -+ config_attr, config_attr_value, (int)max); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ break; -+ } -+ replica_set_backoff_min(r, val); -+ } else { - break; - } -- replica_set_backoff_min(r, val); - } - } else if (strcasecmp(config_attr, type_replicaBackoffMax) == 0) { - if (apply_mods) { -- uint64_t val = atoll(config_attr_value); -- uint64_t min; -- -- if (val <= 0) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number greater than zero.\n", -- config_attr, config_attr_value); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", -- errortext); -- break; -- } -- min = replica_get_backoff_min(r); -- if (val < min) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n", -- config_attr, config_attr_value, (int)min); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ int64_t val = 0; -+ int64_t min; -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) { -+ min = replica_get_backoff_min(r); -+ if (val < min) { -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number more than the min backoff time (%d).\n", -+ config_attr, config_attr_value, (int)min); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", errortext); -+ break; -+ } -+ replica_set_backoff_max(r, val); -+ } else { - break; - } -- replica_set_backoff_max(r, val); - } - } else if (strcasecmp(config_attr, type_replicaPrecisePurge) == 0) { - if (apply_mods) { - if (config_attr_value[0]) { -- PRUint64 on_off = 0; -+ uint64_t on_off = 0; - - if (strcasecmp(config_attr_value, "on") == 0) { - on_off = 1; -@@ -550,19 +542,11 @@ replica_config_modify(Slapi_PBlock *pb, - } - } else if (strcasecmp(config_attr, type_replicaReleaseTimeout) == 0) { - if (apply_mods) { -- long val = atol(config_attr_value); -- -- if (val < 0) { -- *returncode = LDAP_UNWILLING_TO_PERFORM; -- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -- "Attribute %s value (%s) is invalid, must be a number zero or greater.\n", -- config_attr, config_attr_value); -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, -- "replica_config_modify - %s\n", errortext); -- break; -- } else { -- /* Set the timeout */ -+ int64_t val; -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, INT_MAX, returncode, errortext, &val) == 0) { - replica_set_release_timeout(r, val); -+ } else { -+ break; - } - } - } else { -@@ -1011,7 +995,7 @@ replica_config_change_flags(Replica *r, const char *new_flags, char *returntext - PR_ASSERT(r); - - if (apply_mods) { -- PRUint32 flags; -+ uint32_t flags; - - flags = atol(new_flags); - -diff --git a/ldap/servers/plugins/replication/replutil.c b/ldap/servers/plugins/replication/replutil.c -index 1b0446788..7cc132362 100644 ---- a/ldap/servers/plugins/replication/replutil.c -+++ b/ldap/servers/plugins/replication/replutil.c -@@ -1061,3 +1061,29 @@ repl_set_repl_plugin_path(const char *path) - { - replpluginpath = slapi_ch_strdup(path); - } -+ -+int -+repl_config_valid_num(const char *config_attr, char *config_attr_value, int64_t min, int64_t max, -+ int *returncode, char *errortext, int64_t *retval) -+{ -+ int rc = 0; -+ char *endp = NULL; -+ int64_t val; -+ errno = 0; -+ -+ val = strtol(config_attr_value, &endp, 10); -+ if (*endp != '\0' || val < min || val > max || errno == ERANGE) { -+ *returncode = LDAP_UNWILLING_TO_PERFORM; -+ if (errortext){ -+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, -+ "Attribute %s value (%s) is invalid, must be a number between %ld and %ld.", -+ config_attr, config_attr_value, min, max); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl_config_valid_num - %s\n", -+ errortext); -+ } -+ rc = -1; -+ } else { -+ *retval = val; -+ } -+ return rc; -+} --- -2.13.6 - diff --git a/SOURCES/0025-Ticket-49184-Overflow-in-memberof.patch b/SOURCES/0025-Ticket-49184-Overflow-in-memberof.patch new file mode 100644 index 0000000..be478e0 --- /dev/null +++ b/SOURCES/0025-Ticket-49184-Overflow-in-memberof.patch @@ -0,0 +1,299 @@ +From 710b0a6aaf1c648bc8fd33d4ab5bcc859a0ed851 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0026-Ticket-49196-Autotune-generates-crit-messages.patch b/SOURCES/0026-Ticket-49196-Autotune-generates-crit-messages.patch new file mode 100644 index 0000000..a2875dd --- /dev/null +++ b/SOURCES/0026-Ticket-49196-Autotune-generates-crit-messages.patch @@ -0,0 +1,42 @@ +From 8a0b4643e1119e994370089fd52721373e88bb51 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0026-Ticket-49439-cleanallruv-is-not-logging-information.patch b/SOURCES/0026-Ticket-49439-cleanallruv-is-not-logging-information.patch deleted file mode 100644 index 5a52e68..0000000 --- a/SOURCES/0026-Ticket-49439-cleanallruv-is-not-logging-information.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 403c5b61efb5aca3cbea31170d13dfba190ef355 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 2 Nov 2017 12:55:11 -0400 -Subject: [PATCH] Ticket 49439 - cleanallruv is not logging information - -Bug Description: During the logging refector effro from ticket 48978 - a mistake was made and cleanruv_log() was using - LOG_NOTICE (which is not a true log level), it was - supposed to be SLAPI_LOG_NOTICE. - - We also use DEBUG defines to contorl the logging for - debug builds - -Fix Description: Remove the LDAP_DEBUG defines in cleanruv_log, and set - the correct logging severity level. - -https://pagure.io/389-ds-base/issue/49439 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit e1f866a5e3ccce8e061e361c0e3dd11175a8acf2) ---- - .../plugins/replication/repl5_replica_config.c | 30 ++++++++++------------ - 1 file changed, 14 insertions(+), 16 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 9c3c75458..9c8d6adbb 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -1783,7 +1783,7 @@ replica_cleanallruv_thread(void *arg) - /* - * need to sleep between passes - */ -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Not all replicas have received the " -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas have received the " - "cleanallruv extended op, retrying in %d seconds", - interval); - if (!slapi_is_shutting_down()) { -@@ -1825,7 +1825,7 @@ replica_cleanallruv_thread(void *arg) - found_dirty_rid = 0; - } else { - found_dirty_rid = 1; -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Replica is not cleaned yet (%s)", -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica is not cleaned yet (%s)", - agmt_get_long_name(agmt)); - break; - } -@@ -1843,7 +1843,7 @@ replica_cleanallruv_thread(void *arg) - * Need to sleep between passes unless we are shutting down - */ - if (!slapi_is_shutting_down()) { -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Replicas have not been cleaned yet, " -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replicas have not been cleaned yet, " - "retrying in %d seconds", - interval); - PR_Lock(notify_lock); -@@ -1883,10 +1883,10 @@ done: - * Shutdown or abort - */ - if (!is_task_aborted(data->rid) || slapi_is_shutting_down()) { -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Server shutting down. Process will resume at server startup"); - } else { -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, "Task aborted for rid(%d).", data->rid); -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Task aborted for rid(%d).", data->rid); - delete_cleaned_rid_config(data); - remove_cleaned_rid(data->rid); - } -@@ -2053,7 +2053,7 @@ check_replicas_are_done_cleaning(cleanruv_data *data) - break; - } - -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Not all replicas finished cleaning, retrying in %d seconds", - interval); - if (!slapi_is_shutting_down()) { -@@ -2163,7 +2163,7 @@ check_replicas_are_done_aborting(cleanruv_data *data) - if (not_all_aborted == 0) { - break; - } -- cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Not all replicas finished aborting, retrying in %d seconds", interval); - if (!slapi_is_shutting_down()) { - PR_Lock(notify_lock); -@@ -2210,7 +2210,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) - not_all_caughtup = 0; - } else { - not_all_caughtup = 1; -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Replica not caught up (%s)", agmt_get_long_name(agmt)); - break; - } -@@ -2220,7 +2220,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) - if (not_all_caughtup == 0 || is_task_aborted(data->rid)) { - break; - } -- cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Not all replicas caught up, retrying in %d seconds", interval); - if (!slapi_is_shutting_down()) { - PR_Lock(notify_lock); -@@ -2270,7 +2270,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) - not_all_alive = 0; - } else { - not_all_alive = 1; -- cleanruv_log(task, rid, CLEANALLRUV_ID, LOG_NOTICE, "Replica not online (%s)", -+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica not online (%s)", - agmt_get_long_name(agmt)); - break; - } -@@ -2280,7 +2280,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) - if (not_all_alive == 0 || is_task_aborted(rid)) { - break; - } -- cleanruv_log(task, rid, CLEANALLRUV_ID, LOG_NOTICE, "Not all replicas online, retrying in %d seconds...", -+ cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas online, retrying in %d seconds...", - interval); - - if (!slapi_is_shutting_down()) { -@@ -3063,7 +3063,7 @@ replica_abort_task_thread(void *arg) - * Need to sleep between passes. unless we are shutting down - */ - if (!slapi_is_shutting_down()) { -- cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, LOG_NOTICE, "Retrying in %d seconds", interval); -+ cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Retrying in %d seconds", interval); - PR_Lock(notify_lock); - PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval)); - PR_Unlock(notify_lock); -@@ -3184,7 +3184,7 @@ replica_cleanallruv_send_extop(Repl_Agmt *ra, cleanruv_data *clean_data, int che - /* extop was accepted */ - rc = 0; - } else { -- cleanruv_log(clean_data->task, clean_data->rid, CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(clean_data->task, clean_data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Replica %s does not support the CLEANALLRUV task. " - "Sending replica CLEANRUV task...", - slapi_sdn_get_dn(agmt_get_dn_byref(ra))); -@@ -3352,7 +3352,7 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *basedn, char *rid_text, - csn_init_by_string(repl_max, remote_maxcsn); - if (csn_compare(repl_max, max) < 0) { - /* we are not caught up yet, free, and return */ -- cleanruv_log(task, atoi(rid_text), CLEANALLRUV_ID, LOG_NOTICE, -+ cleanruv_log(task, atoi(rid_text), CLEANALLRUV_ID, SLAPI_LOG_NOTICE, - "Replica maxcsn (%s) is not caught up with deleted replica's maxcsn(%s)", - remote_maxcsn, maxcsn); - rc = -1; -@@ -3525,7 +3525,6 @@ stop_ruv_cleaning() - void - cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...) - { --#ifdef LDAP_DEBUG - va_list ap1; - va_list ap2; - va_list ap3; -@@ -3550,7 +3549,6 @@ cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fm - va_end(ap2); - va_end(ap3); - va_end(ap4); --#endif - } - - char * --- -2.13.6 - diff --git a/SOURCES/0027-Issue-49221-During-an-upgrade-the-provided-localhost.patch b/SOURCES/0027-Issue-49221-During-an-upgrade-the-provided-localhost.patch new file mode 100644 index 0000000..8eb11b7 --- /dev/null +++ b/SOURCES/0027-Issue-49221-During-an-upgrade-the-provided-localhost.patch @@ -0,0 +1,36 @@ +From 4e66114109263fff6b13192e07be9bbd9e493fee Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0027-Ticket-48393-fix-copy-and-paste-error.patch b/SOURCES/0027-Ticket-48393-fix-copy-and-paste-error.patch deleted file mode 100644 index d59c217..0000000 --- a/SOURCES/0027-Ticket-48393-fix-copy-and-paste-error.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3d045a240bb32b66e15401bf89eff5b980420b24 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 3 Nov 2017 12:18:26 -0400 -Subject: [PATCH] Ticket 48393 - fix copy and paste error - -Description: Copy and paste error when validating repl agmt - -https://pagure.io/389-ds-base/issue/48393 - -Reviewed by: mreynolds(one line commit rule) - -(cherry picked from commit 431647039c5e6d860d8866542050d456f69bb600) ---- - ldap/servers/plugins/replication/repl5_agmt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c -index 78fb91ae6..ee396c8ef 100644 ---- a/ldap/servers/plugins/replication/repl5_agmt.c -+++ b/ldap/servers/plugins/replication/repl5_agmt.c -@@ -339,7 +339,7 @@ agmt_new_from_entry(Slapi_Entry *e) - ra->flowControlWindow = DEFAULT_FLOWCONTROL_WINDOW; - if ((val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaFlowControlWindow))){ - int64_t flow; -- if (repl_config_valid_num(type_nsds5ReplicaTimeout, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) { -+ if (repl_config_valid_num(type_nsds5ReplicaFlowControlWindow, val, 0, INT_MAX, &rc, errormsg, &flow) != 0) { - goto loser; - } - slapi_ch_free_string(&val); --- -2.13.6 - diff --git a/SOURCES/0028-Ticket-48864-Add-cgroup-memory-limit-detection-to-38.patch b/SOURCES/0028-Ticket-48864-Add-cgroup-memory-limit-detection-to-38.patch new file mode 100644 index 0000000..1a6d37b --- /dev/null +++ b/SOURCES/0028-Ticket-48864-Add-cgroup-memory-limit-detection-to-38.patch @@ -0,0 +1,4106 @@ +From 57b6e5afb6265363ede667ad450e267f8a803b9e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 19 Apr 2017 13:37:10 -0400 +Subject: [PATCH] Ticket 48864 - Add cgroup memory limit detection to 389-ds + +Bug Description: Previously our memory limits only check hardware + limits and shell resource limits. However, we may be in a container + like docker or lxc, and unable to detect these limits. This can lead + to crash conditions or worse, especially with autosizing + on import we may have conditions where the server may not + even be able to install. + +Fix Description: Add support for cgroup memory limit detection + so that we can properly determine our resource availability regardless + of lxc, docker, systemd or others. + +https://pagure.io/389-ds-base/issue/48864 + +Author: wibrown + +Review by: mreynolds (Thanks!) +--- + Makefile.am | 7 +- + ldap/servers/plugins/acl/acl.c | 18 +- + ldap/servers/plugins/acl/acl.h | 16 - + ldap/servers/plugins/acl/aclanom.c | 8 +- + ldap/servers/plugins/dna/dna.c | 50 ++- + ldap/servers/plugins/posix-winsync/posix-winsync.c | 4 +- + ldap/servers/plugins/replication/repl.h | 17 +- + .../plugins/replication/repl5_inc_protocol.c | 2 +- + ldap/servers/plugins/replication/repl5_init.c | 2 +- + ldap/servers/plugins/replication/repl5_plugins.c | 2 +- + ldap/servers/plugins/replication/repl5_replica.c | 8 +- + ldap/servers/plugins/replication/repl5_total.c | 4 +- + ldap/servers/plugins/replication/repl_connext.c | 20 +- + ldap/servers/plugins/replication/repl_extop.c | 26 +- + ldap/servers/plugins/sync/sync_persist.c | 6 +- + ldap/servers/plugins/syntaxes/validate_task.c | 6 +- + ldap/servers/plugins/usn/usn.c | 8 +- + ldap/servers/slapd/abandon.c | 8 +- + ldap/servers/slapd/add.c | 4 +- + ldap/servers/slapd/auth.c | 18 +- + ldap/servers/slapd/back-ldbm/back-ldbm.h | 23 +- + ldap/servers/slapd/back-ldbm/cache.c | 34 +- + ldap/servers/slapd/back-ldbm/dblayer.c | 72 ++-- + ldap/servers/slapd/back-ldbm/dblayer.h | 8 - + ldap/servers/slapd/back-ldbm/import-threads.c | 2 +- + ldap/servers/slapd/back-ldbm/import.c | 12 +- + ldap/servers/slapd/back-ldbm/ldbm_config.c | 32 +- + ldap/servers/slapd/back-ldbm/ldbm_delete.c | 4 +- + .../servers/slapd/back-ldbm/ldbm_instance_config.c | 20 +- + ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 4 +- + ldap/servers/slapd/back-ldbm/ldbm_search.c | 4 +- + ldap/servers/slapd/back-ldbm/misc.c | 2 +- + ldap/servers/slapd/back-ldbm/monitor.c | 10 +- + ldap/servers/slapd/back-ldbm/perfctrs.h | 2 +- + ldap/servers/slapd/back-ldbm/start.c | 113 +++---- + ldap/servers/slapd/bind.c | 8 +- + ldap/servers/slapd/compare.c | 2 +- + ldap/servers/slapd/connection.c | 72 ++-- + ldap/servers/slapd/conntable.c | 8 +- + ldap/servers/slapd/control.c | 2 +- + ldap/servers/slapd/daemon.c | 48 +-- + ldap/servers/slapd/delete.c | 2 +- + ldap/servers/slapd/entry.c | 2 +- + ldap/servers/slapd/extendop.c | 4 +- + ldap/servers/slapd/log.c | 10 +- + ldap/servers/slapd/modify.c | 12 +- + ldap/servers/slapd/modrdn.c | 6 +- + ldap/servers/slapd/monitor.c | 8 +- + ldap/servers/slapd/operation.c | 6 +- + ldap/servers/slapd/opshared.c | 4 +- + ldap/servers/slapd/pagedresults.c | 2 +- + ldap/servers/slapd/psearch.c | 10 +- + ldap/servers/slapd/result.c | 12 +- + ldap/servers/slapd/sasl_io.c | 52 +-- + ldap/servers/slapd/saslbind.c | 2 +- + ldap/servers/slapd/search.c | 2 +- + ldap/servers/slapd/slap.h | 9 +- + ldap/servers/slapd/slapi-plugin.h | 14 +- + ldap/servers/slapd/slapi-private.h | 38 ++- + ldap/servers/slapd/slapi_pal.c | 311 +++++++++++++++++ + ldap/servers/slapd/slapi_pal.h | 62 ++++ + ldap/servers/slapd/snmp_collator.c | 2 +- + ldap/servers/slapd/unbind.c | 6 +- + ldap/servers/slapd/util.c | 376 +-------------------- + test/libslapd/spal/meminfo.c | 54 +++ + test/libslapd/test.c | 2 + + test/test_slapd.h | 5 + + 67 files changed, 870 insertions(+), 859 deletions(-) + create mode 100644 ldap/servers/slapd/slapi_pal.c + create mode 100644 ldap/servers/slapd/slapi_pal.h + create mode 100644 test/libslapd/spal/meminfo.c + +diff --git a/Makefile.am b/Makefile.am +index 485a460..429a345 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -481,6 +481,7 @@ dist_noinst_HEADERS = \ + ldap/servers/slapd/pw_verify.h \ + ldap/servers/slapd/secerrstrs.h \ + ldap/servers/slapd/slap.h \ ++ ldap/servers/slapd/slapi_pal.h \ + ldap/servers/slapd/slapi-plugin-compat4.h \ + ldap/servers/slapd/slapi-plugin.h \ + ldap/servers/slapd/slapi-private.h \ +@@ -850,6 +851,7 @@ pkgconfig_DATA = src/pkgconfig/dirsrv.pc \ + # header files + #------------------------ + serverinc_HEADERS = ldap/servers/plugins/replication/repl-session-plugin.h \ ++ ldap/servers/slapd/slapi_pal.h \ + ldap/servers/slapd/slapi-plugin.h \ + ldap/servers/plugins/replication/winsync-plugin.h \ + src/nunc-stans/include/nunc-stans.h \ +@@ -1219,6 +1221,7 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \ + ldap/servers/slapd/value.c \ + ldap/servers/slapd/valueset.c \ + ldap/servers/slapd/vattr.c \ ++ ldap/servers/slapd/slapi_pal.c \ + $(libavl_a_SOURCES) + + libslapd_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(SASL_INCLUDES) @db_inc@ $(SVRCORE_INCLUDES) @kerberos_inc@ @pcre_inc@ +@@ -2004,7 +2007,9 @@ test_slapd_SOURCES = test/main.c \ + test/libslapd/counters/atomic.c \ + test/libslapd/pblock/analytics.c \ + test/libslapd/pblock/v3_compat.c \ +- test/libslapd/operation/v3_compat.c ++ test/libslapd/operation/v3_compat.c \ ++ test/libslapd/spal/meminfo.c ++ + test_slapd_LDADD = libslapd.la + test_slapd_LDFLAGS = $(AM_CPPFLAGS) $(CMOCKA_LINKS) + ### WARNING: Slap.h needs cert.h, which requires the -I/lib/ldaputil!!! +diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c +index 48b8efc..561dd91 100644 +--- a/ldap/servers/plugins/acl/acl.c ++++ b/ldap/servers/plugins/acl/acl.c +@@ -276,7 +276,7 @@ acl_access_allowed( + + if ( !privateBackend && (be_readonly || slapi_config_get_readonly () )){ + slapi_log_err(loglevel, plugin_name, +- "acl_access_allowed - conn=%" NSPRIu64 " op=%d (main): Deny %s on entry(%s)" ++ "acl_access_allowed - conn=%" PRIu64 " op=%d (main): Deny %s on entry(%s)" + ": readonly backend\n", + o_connid, o_opid, + acl_access2str(access), +@@ -289,7 +289,7 @@ acl_access_allowed( + TNF_PROBE_0_DEBUG(acl_skipaccess_start,"ACL",""); + if ( acl_skip_access_check ( pb, e, access )) { + slapi_log_err(loglevel, plugin_name, +- "acl_access_allowed - conn=%" NSPRIu64 " op=%d (main): Allow %s on entry(%s)" ++ "acl_access_allowed - conn=%" PRIu64 " op=%d (main): Allow %s on entry(%s)" + ": root user\n", + o_connid, o_opid, + acl_access2str(access), +@@ -448,7 +448,7 @@ acl_access_allowed( + TNF_PROBE_0_DEBUG(acl_entry_first_touch_start,"ACL",""); + + slapi_log_err(loglevel, plugin_name, +- "acl_access_allowed - #### conn=%" NSPRIu64 " op=%d binddn=\"%s\"\n", ++ "acl_access_allowed - #### conn=%" PRIu64 " op=%d binddn=\"%s\"\n", + o_connid, o_opid, clientDn); + aclpb->aclpb_stat_total_entries++; + +@@ -776,7 +776,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + null_user); + if (strcasecmp(right, access_str_moddn) == 0) { + slapi_log_err(loglevel, plugin_name, "print_access_control_summary - " +- "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)" ++ "conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)" + ": %s\n", + o_connid, o_opid, + source, +@@ -790,7 +790,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + + } else { + slapi_log_err(loglevel, plugin_name, +- "print_access_control_summary - conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)" ++ "print_access_control_summary - conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)" + ": %s\n", + o_connid, o_opid, + source, +@@ -805,7 +805,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + proxy_user = null_user; + if (strcasecmp(right, access_str_moddn) == 0) { + slapi_log_err(loglevel, plugin_name, +- "print_access_control_summary - conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)" ++ "print_access_control_summary - conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)" + ": %s\n", + o_connid, o_opid, + source, +@@ -819,7 +819,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + + } else { + slapi_log_err(loglevel, plugin_name, +- "print_access_control_summary - conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)" ++ "print_access_control_summary - conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)" + ": %s\n", + o_connid, o_opid, + source, +@@ -834,7 +834,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + } else { + if (strcasecmp(right, access_str_moddn) == 0) { + slapi_log_err(loglevel, plugin_name, +- "print_access_control_summary - conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to %s" ++ "print_access_control_summary - conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to %s" + ": %s\n", + o_connid, o_opid, + source, +@@ -848,7 +848,7 @@ print_access_control_summary( char *source, int ret_val, char *clientDn, + + } else { + slapi_log_err(loglevel, plugin_name, +- "print_access_control_summary - conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to %s" ++ "print_access_control_summary - conn=%" PRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to %s" + ": %s\n", + o_connid, o_opid, + source, +diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h +index 91f5071..8b3486c 100644 +--- a/ldap/servers/plugins/acl/acl.h ++++ b/ldap/servers/plugins/acl/acl.h +@@ -20,22 +20,6 @@ + #ifndef _ACL_H_ + #define _ACL_H_ + +-/* Required to get portable printf/scanf format macros */ +-#ifdef HAVE_INTTYPES_H +-#include +- +-/* NSPR uses the print macros a bit differently than ANSI C. We +- * need to use ll for a 64-bit integer, even when a long is 64-bit. +- */ +-#undef PRIu64 +-#define PRIu64 "llu" +-#undef PRI64 +-#define PRI64 "ll" +- +-#else +-#error Need to define portable format macros such as PRIu64 +-#endif /* HAVE_INTTYPES_H */ +- + #include + #include + #include +diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c +index 5462d87..96d0d9f 100644 +--- a/ldap/servers/plugins/acl/aclanom.c ++++ b/ldap/servers/plugins/acl/aclanom.c +@@ -523,7 +523,7 @@ aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry * + aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target); + if (access & SLAPI_ACL_MODDN) { + slapi_log_err(loglevel, plugin_name, +- "aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) (from %s) to anonymous: acidn=\"%s\"\n", ++ "aclanom_match_profile - conn=%" PRIu64 " op=%d: Allow access on entry(%s).attr(%s) (from %s) to anonymous: acidn=\"%s\"\n", + o_connid, o_opid, + ndn, + attr ? attr:"NULL", +@@ -532,7 +532,7 @@ aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry * + + } else { + slapi_log_err(loglevel, plugin_name, +- "aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n", ++ "aclanom_match_profile - conn=%" PRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n", + o_connid, o_opid, + ndn, + attr ? attr:"NULL", +@@ -541,13 +541,13 @@ aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry * + } else { + if (access & SLAPI_ACL_MODDN) { + slapi_log_err(loglevel, plugin_name, +- "aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) (from %s) to anonymous\n", ++ "aclanom_match_profile - conn=%" PRIu64 " op=%d: Deny access on entry(%s).attr(%s) (from %s) to anonymous\n", + o_connid, o_opid, + ndn, attr ? attr:"NULL" , + aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL"); + } else { + slapi_log_err(loglevel, plugin_name, +- "aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n", ++ "aclanom_match_profile - conn=%" PRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n", + o_connid, o_opid, + ndn, attr ? attr:"NULL" ); + } +diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c +index 34011b9..a085941 100644 +--- a/ldap/servers/plugins/dna/dna.c ++++ b/ldap/servers/plugins/dna/dna.c +@@ -23,14 +23,6 @@ + #include "slapi-private.h" + #include "prclist.h" + +-/* Required to get portable printf/scanf format macros */ +-#ifdef HAVE_INTTYPES_H +-#include +- +-#else +-#error Need to define portable format macros such as PRIu64 +-#endif /* HAVE_INTTYPES_H */ +- + #include + + #define DNA_PLUGIN_SUBSYSTEM "dna-plugin" +@@ -997,7 +989,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) + } + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, +- "dna_parse_config_entry - %s [%" NSPRIu64 "]\n", DNA_NEXTVAL, ++ "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_NEXTVAL, + entry->nextval); + + value = slapi_entry_attr_get_charptr(e, DNA_PREFIX); +@@ -1026,7 +1018,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) + } + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, +- "dna_parse_config_entry - %s [%" NSPRIu64 "]\n", DNA_INTERVAL, entry->interval); ++ "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_INTERVAL, entry->interval); + #endif + + value = slapi_entry_attr_get_charptr(e, DNA_GENERATE); +@@ -1126,7 +1118,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) + } + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, +- "dna_parse_config_entry - %s [%" NSPRIu64 "]\n", DNA_MAXVAL, ++ "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_MAXVAL, + entry->maxval); + + /* get the global bind dn and password(if any) */ +@@ -1256,7 +1248,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) + } + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, +- "dna_parse_config_entry - %s [%" NSPRIu64 "]\n", DNA_THRESHOLD, ++ "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_THRESHOLD, + entry->threshold); + + value = slapi_entry_attr_get_charptr(e, DNA_RANGE_REQUEST_TIMEOUT); +@@ -1268,7 +1260,7 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply) + } + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, +- "dna_parse_config_entry - %s [%" NSPRIu64 "]\n", DNA_RANGE_REQUEST_TIMEOUT, ++ "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_RANGE_REQUEST_TIMEOUT, + entry->timeout); + + value = slapi_entry_attr_get_charptr(e, DNA_NEXT_RANGE); +@@ -2307,7 +2299,7 @@ dna_first_free_value(struct configEntry *config_entry, + return LDAP_OPERATIONS_ERROR; + } + +- filter = slapi_ch_smprintf("(&%s(&(%s>=%" NSPRIu64 ")(%s<=%" NSPRIu64 ")))", ++ filter = slapi_ch_smprintf("(&%s(&(%s>=%" PRIu64 ")(%s<=%" PRIu64 ")))", + config_entry->filter, + config_entry->types[0], tmpval, + config_entry->types[0], config_entry->maxval); +@@ -2497,7 +2489,7 @@ static int dna_get_next_value(struct configEntry *config_entry, + if ((config_entry->maxval == -1) || + (nextval <= (config_entry->maxval + config_entry->interval))) { + /* try to set the new next value in the config entry */ +- snprintf(next_value, sizeof(next_value),"%" NSPRIu64, nextval); ++ snprintf(next_value, sizeof(next_value),"%" PRIu64, nextval); + + /* set up our replace modify operation */ + replace_val[0] = next_value; +@@ -2524,7 +2516,7 @@ static int dna_get_next_value(struct configEntry *config_entry, + + if (LDAP_SUCCESS == ret) { + slapi_ch_free_string(next_value_ret); +- *next_value_ret = slapi_ch_smprintf("%" NSPRIu64, setval); ++ *next_value_ret = slapi_ch_smprintf("%" PRIu64, setval); + if (NULL == *next_value_ret) { + ret = LDAP_OPERATIONS_ERROR; + goto done; +@@ -2609,7 +2601,7 @@ dna_update_shared_config(struct configEntry *config_entry) + + /* We store the number of remaining assigned values + * in the shared config entry. */ +- snprintf(remaining_vals, sizeof(remaining_vals),"%" NSPRIu64, ++ snprintf(remaining_vals, sizeof(remaining_vals),"%" PRIu64, + config_entry->remaining); + + /* set up our replace modify operation */ +@@ -2709,7 +2701,7 @@ dna_update_next_range(struct configEntry *config_entry, + int ret = 0; + + /* Try to set the new next range in the config entry. */ +- snprintf(nextrange_value, sizeof(nextrange_value), "%" NSPRIu64 "-%" NSPRIu64, ++ snprintf(nextrange_value, sizeof(nextrange_value), "%" PRIu64 "-%" PRIu64, + lower, upper); + + /* set up our replace modify operation */ +@@ -2778,8 +2770,8 @@ dna_activate_next_range(struct configEntry *config_entry) + int ret = 0; + + /* Setup the modify operation for the config entry */ +- snprintf(maxval_val, sizeof(maxval_val),"%" NSPRIu64, config_entry->next_range_upper); +- snprintf(nextval_val, sizeof(nextval_val),"%" NSPRIu64, config_entry->next_range_lower); ++ snprintf(maxval_val, sizeof(maxval_val),"%" PRIu64, config_entry->next_range_upper); ++ snprintf(nextval_val, sizeof(nextval_val),"%" PRIu64, config_entry->next_range_lower); + + maxval_vals[0] = maxval_val; + maxval_vals[1] = 0; +@@ -3319,7 +3311,7 @@ dna_create_valcheck_filter(struct configEntry *config_entry, PRUint64 value, cha + * - the string length of the filter in the config + * - the string length sum of all configured types + * - 23 bytes for each type (20 for the max string +- * representation of a NSPRIu64, 3 for "(=)" ++ * representation of a PRIu64, 3 for "(=)" + * - 3 bytes for the beginning and end of the filter - "(&" and ")" + * - 3 bytes to OR together multiple types (if present) - "(|" and ")" + * - the string length of the prefix (if one is configured) for each type +@@ -3556,8 +3548,8 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr) + (config_entry->remaining <= config_entry->threshold)) { + slapi_log_err(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM, + "_dna_pre_op_add - Passed threshold of %" +- NSPRIu64 " remaining values " +- "for range %s. (%" NSPRIu64 " values remain)\n", ++ PRIu64 " remaining values " ++ "for range %s. (%" PRIu64 " values remain)\n", + config_entry->threshold, config_entry->dn, + config_entry->remaining); + dna_fix_maxval(config_entry, 0); +@@ -3828,8 +3820,8 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods, char **e + (config_entry->remaining <= config_entry->threshold)) { + slapi_log_err(SLAPI_LOG_ERR, DNA_PLUGIN_SUBSYSTEM, + "_dna_pre_op_modify - Passed threshold of %" +- NSPRIu64 " remaining values " +- "for range %s. (%" NSPRIu64 " values remain)\n", ++ PRIu64 " remaining values " ++ "for range %s. (%" PRIu64 " values remain)\n", + config_entry->threshold, config_entry->dn, + config_entry->remaining); + dna_fix_maxval(config_entry, 0); +@@ -4411,8 +4403,8 @@ static int dna_extend_exop(Slapi_PBlock *pb) + char highstr[16]; + + /* Create the exop response */ +- snprintf(lowstr, sizeof(lowstr), "%" NSPRIu64, lower); +- snprintf(highstr, sizeof(highstr), "%" NSPRIu64, upper); ++ snprintf(lowstr, sizeof(lowstr), "%" PRIu64, lower); ++ snprintf(highstr, sizeof(highstr), "%" PRIu64, upper); + range_low.bv_val = lowstr; + range_low.bv_len = strlen(range_low.bv_val); + range_high.bv_val = highstr; +@@ -4445,7 +4437,7 @@ static int dna_extend_exop(Slapi_PBlock *pb) + ber_bvfree(respdata); + + slapi_log_err(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM, +- "dna_extend_exop - Released range %" NSPRIu64 "-%" NSPRIu64 ".\n", ++ "dna_extend_exop - Released range %" PRIu64 "-%" PRIu64 ".\n", + lower, upper); + } + +@@ -4588,7 +4580,7 @@ dna_release_range(char *range_dn, PRUint64 *lower, PRUint64 *upper) + *lower = *upper - release + 1; + + /* try to set the new maxval in the config entry */ +- snprintf(max_value, sizeof(max_value),"%" NSPRIu64, (*lower - 1)); ++ snprintf(max_value, sizeof(max_value),"%" PRIu64, (*lower - 1)); + + /* set up our replace modify operation */ + replace_val[0] = max_value; +diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c +index 63444e5..21e4ad0 100644 +--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c ++++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c +@@ -270,7 +270,7 @@ sync_acct_disable(void *cbdata, /* the usual domain config data */ + if (update_entry) { + slapi_entry_attr_set_ulong(update_entry, "userAccountControl", adval); + slapi_log_err(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, +- "<-- sync_acct_disable - %s AD account [%s] - new value is [%" NSPRIu64 "]\n", ++ "<-- sync_acct_disable - %s AD account [%s] - new value is [%" PRIu64 "]\n", + (ds_is_enabled) ? "enabled" : "disabled", slapi_entry_get_dn_const(update_entry), adval); + } else { + /* iterate through the mods - if there is already a mod +@@ -326,7 +326,7 @@ sync_acct_disable(void *cbdata, /* the usual domain config data */ + mod_bval->bv_len = strlen(acctvalstr); + } + slapi_log_err(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, +- "<-- sync_acct_disable - %s AD account [%s] - new value is [%" NSPRIu64 "]\n", ++ "<-- sync_acct_disable - %s AD account [%s] - new value is [%" PRIu64 "]\n", + (ds_is_enabled) ? "enabled" : "disabled", slapi_entry_get_dn_const(ad_entry), adval); + } + } +diff --git a/ldap/servers/plugins/replication/repl.h b/ldap/servers/plugins/replication/repl.h +index 89ad481..9460ca9 100644 +--- a/ldap/servers/plugins/replication/repl.h ++++ b/ldap/servers/plugins/replication/repl.h +@@ -15,21 +15,8 @@ + #ifndef _REPL_H_ + #define _REPL_H_ + +-/* Required to get portable printf/scanf format macros */ +-#ifdef HAVE_INTTYPES_H +-#include +- +-/* NSPR uses the print macros a bit differently than ANSI C. We +- * need to use ll for a 64-bit integer, even when a long is 64-bit. +- */ +-#undef PRIu64 +-#define PRIu64 "llu" +-#undef PRI64 +-#define PRI64 "ll" +- +-#else +-#error Need to define portable format macros such as PRIu64 +-#endif /* HAVE_INTTYPES_H */ ++/* Provides our int types and platform specific requirements. */ ++#include + + #include + #include +diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c +index a5ae885..36c279e 100644 +--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c ++++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c +@@ -2104,7 +2104,7 @@ repl5_inc_stop(Private_Repl_Protocol *prp) + /* Isn't listening. Do something drastic. */ + return_value = -1; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, +- "repl5_inc_stop - %s: Protocol does not stop after %" NSPRIu64 " seconds\n", ++ "repl5_inc_stop - %s: Protocol does not stop after %" PRIu64 " seconds\n", + agmt_get_long_name(prp->agmt), timeout); + } + else +diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c +index 9549dcf..edffb84 100644 +--- a/ldap/servers/plugins/replication/repl5_init.c ++++ b/ldap/servers/plugins/replication/repl5_init.c +@@ -208,7 +208,7 @@ get_repl_session_id (Slapi_PBlock *pb, char *idstr, CSN **csn) + /* Avoid "Connection is NULL and hence cannot access SLAPI_CONN_ID" */ + if (opid) { + slapi_pblock_get (pb, SLAPI_CONN_ID, &connid); +- snprintf (idstr, REPL_SESSION_ID_SIZE, "conn=%" NSPRIu64 " op=%d", ++ snprintf (idstr, REPL_SESSION_ID_SIZE, "conn=%" PRIu64 " op=%d", + connid, opid); + } + +diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c +index 357c093..ebcc230 100644 +--- a/ldap/servers/plugins/replication/repl5_plugins.c ++++ b/ldap/servers/plugins/replication/repl5_plugins.c +@@ -1335,7 +1335,7 @@ process_postop (Slapi_PBlock *pb) + { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "process_postop - Failed to apply update (%s) error (%d). " +- "Aborting replication session(conn=%" NSPRIu64 " op=%d)\n", ++ "Aborting replication session(conn=%" PRIu64 " op=%d)\n", + csn_as_string(opcsn, PR_FALSE, csn_str), retval, + connid, opid); + /* +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 5718a98..a106f8b 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -596,7 +596,7 @@ replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opi + + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_get_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Replica in use locking_purl=%s\n", + connid, opid, + slapi_sdn_get_dn(r->repl_root), +@@ -620,7 +620,7 @@ replica_get_exclusive_access(Replica *r, PRBool *isInc, PRUint64 connid, int opi + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_get_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": Acquired replica\n", ++ "conn=%" PRIu64 " op=%d repl=\"%s\": Acquired replica\n", + connid, opid, + slapi_sdn_get_dn(r->repl_root)); + r->repl_state_flags |= REPLICA_IN_USE; +@@ -664,13 +664,13 @@ replica_relinquish_exclusive_access(Replica *r, PRUint64 connid, int opid) + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Replica not in use\n", + connid, opid, slapi_sdn_get_dn(r->repl_root)); + } else { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Released replica held by locking_purl=%s\n", + connid, opid, + slapi_sdn_get_dn(r->repl_root), r->locking_purl); +diff --git a/ldap/servers/plugins/replication/repl5_total.c b/ldap/servers/plugins/replication/repl5_total.c +index af570a8..064a099 100644 +--- a/ldap/servers/plugins/replication/repl5_total.c ++++ b/ldap/servers/plugins/replication/repl5_total.c +@@ -853,7 +853,7 @@ multimaster_extop_NSDS50ReplicationEntry(Slapi_PBlock *pb) + const char *dn = slapi_entry_get_dn_const(e); + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_NSDS50ReplicationEntry - " +- "Error %d: could not import entry dn %s for total update operation conn=%" NSPRIu64 " op=%d\n", ++ "Error %d: could not import entry dn %s for total update operation conn=%" PRIu64 " op=%d\n", + rc, dn, connid, opid); + rc = -1; + } +@@ -864,7 +864,7 @@ multimaster_extop_NSDS50ReplicationEntry(Slapi_PBlock *pb) + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_NSDS50ReplicationEntry - " + "Error %d: could not decode the total update extop " +- "for total update operation conn=%" NSPRIu64 " op=%d\n", ++ "for total update operation conn=%" PRIu64 " op=%d\n", + rc, connid, opid); + } + +diff --git a/ldap/servers/plugins/replication/repl_connext.c b/ldap/servers/plugins/replication/repl_connext.c +index 29dc2a7..ba0fa15 100644 +--- a/ldap/servers/plugins/replication/repl_connext.c ++++ b/ldap/servers/plugins/replication/repl_connext.c +@@ -84,7 +84,7 @@ void consumer_connection_extension_destructor (void *ext, void *object, void *pa + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_destructor - " + "Aborting total update in progress for replicated " +- "area %s connid=%" NSPRIu64 "\n", slapi_sdn_get_dn(repl_root_sdn), connid); ++ "area %s connid=%" PRIu64 "\n", slapi_sdn_get_dn(repl_root_sdn), connid); + slapi_stop_bulk_import(pb); + } + else +@@ -156,7 +156,7 @@ consumer_connection_extension_acquire_exclusive_access(void* conn, PRUint64 conn + ret = connext; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_acquire_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Acquired consumer connection extension\n", ++ "conn=%" PRIu64 " op=%d Acquired consumer connection extension\n", + connid, opid); + } + else if (opid == connext->in_use_opid) +@@ -164,14 +164,14 @@ consumer_connection_extension_acquire_exclusive_access(void* conn, PRUint64 conn + ret = connext; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_acquire_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Reacquired consumer connection extension\n", ++ "conn=%" PRIu64 " op=%d Reacquired consumer connection extension\n", + connid, opid); + } + else + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_acquire_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Could not acquire consumer connection extension; it is in use by op=%d\n", ++ "conn=%" PRIu64 " op=%d Could not acquire consumer connection extension; it is in use by op=%d\n", + connid, opid, connext->in_use_opid); + } + +@@ -182,7 +182,7 @@ consumer_connection_extension_acquire_exclusive_access(void* conn, PRUint64 conn + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_acquire_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Could not acquire consumer extension, it is NULL!\n", ++ "conn=%" PRIu64 " op=%d Could not acquire consumer extension, it is NULL!\n", + connid, opid); + } + +@@ -221,7 +221,7 @@ consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 c + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Consumer connection extension is not in use\n", ++ "conn=%" PRIu64 " op=%d Consumer connection extension is not in use\n", + connid, opid); + ret = 2; + } +@@ -230,7 +230,7 @@ consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 c + /* step 4, relinquish it (normal) */ + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Relinquishing consumer connection extension\n", ++ "conn=%" PRIu64 " op=%d Relinquishing consumer connection extension\n", + connid, opid); + connext->in_use_opid = -1; + ret = 1; +@@ -240,7 +240,7 @@ consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 c + /* step 4, relinquish it (forced) */ + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Forced to relinquish consumer connection extension held by op=%d\n", ++ "conn=%" PRIu64 " op=%d Forced to relinquish consumer connection extension held by op=%d\n", + connid, opid, connext->in_use_opid); + connext->in_use_opid = -1; + ret = 1; +@@ -249,7 +249,7 @@ consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 c + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Not relinquishing consumer connection extension, it is held by op=%d!\n", ++ "conn=%" PRIu64 " op=%d Not relinquishing consumer connection extension, it is held by op=%d!\n", + connid, opid, connext->in_use_opid); + } + +@@ -260,7 +260,7 @@ consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 c + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "consumer_connection_extension_relinquish_exclusive_access - " +- "conn=%" NSPRIu64 " op=%d Could not relinquish consumer extension, it is NULL!\n", ++ "conn=%" PRIu64 " op=%d Could not relinquish consumer extension, it is NULL!\n", + connid, opid); + } + +diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c +index 80580f9..412caec 100644 +--- a/ldap/servers/plugins/replication/repl_extop.c ++++ b/ldap/servers/plugins/replication/repl_extop.c +@@ -668,7 +668,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + connext->repl_protocol_version = REPL_PROTOCOL_50_INCREMENTAL; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": Begin incremental protocol\n", ++ "conn=%" PRIu64 " op=%d repl=\"%s\": Begin incremental protocol\n", + connid, opid, repl_root); + isInc = PR_TRUE; + } +@@ -695,7 +695,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + } + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": Begin total protocol\n", ++ "conn=%" PRIu64 " op=%d repl=\"%s\": Begin total protocol\n", + connid, opid, repl_root); + isInc = PR_FALSE; + } +@@ -705,7 +705,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + connext->repl_protocol_version = REPL_PROTOCOL_50_INCREMENTAL; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": Begin 7.1 incremental protocol\n", ++ "conn=%" PRIu64 " op=%d repl=\"%s\": Begin 7.1 incremental protocol\n", + connid, opid, repl_root); + isInc = PR_TRUE; + } +@@ -718,7 +718,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + } + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": Begin 7.1 total protocol\n", ++ "conn=%" PRIu64 " op=%d repl=\"%s\": Begin 7.1 total protocol\n", + connid, opid, repl_root); + isInc = PR_FALSE; + } +@@ -741,7 +741,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d replica=\"%s\": " ++ "conn=%" PRIu64 " op=%d replica=\"%s\": " + "Replica is being configured: try again later\n", + connid, opid, repl_root); + response = NSDS50_REPL_REPLICA_BUSY; +@@ -814,7 +814,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Excessive clock skew from supplier RUV\n", + connid, opid, repl_root); + response = NSDS50_REPL_EXCESSIVE_CLOCK_SKEW; +@@ -852,7 +852,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + if (check_replica_id_uniqueness(replica, supplier_ruv) != 0){ + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Replica has same replicaID %d as supplier\n", + connid, opid, repl_root, replica_get_rid(replica)); + response = NSDS50_REPL_REPLICAID_ERROR; +@@ -865,7 +865,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + * the session's conn id and op id to identify the the supplier. + */ + /* junkrc = ruv_get_first_id_and_purl(supplier_ruv, &junkrid, &locking_purl); */ +- snprintf(locking_session, sizeof(locking_session), "conn=%" NSPRIu64 " id=%d", ++ snprintf(locking_session, sizeof(locking_session), "conn=%" PRIu64 " id=%d", + connid, opid); + locking_purl = &locking_session[0]; + if (replica_get_exclusive_access(replica, &isInc, connid, opid, +@@ -892,7 +892,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + int max = 480 * 5; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "374 - Starting sleep: connext->repl_protocol_version == %d\n", + connid, opid, repl_root, connext->repl_protocol_version); + +@@ -902,7 +902,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "374 - Finished sleep: connext->repl_protocol_version == %d\n", + connid, opid, repl_root, connext->repl_protocol_version); + } +@@ -997,7 +997,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) + response = NSDS50_REPL_INTERNAL_ERROR; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "Unexpected update protocol received: %d. " + "Expected incremental or total.\n", + connid, opid, repl_root, connext->repl_protocol_version); +@@ -1039,7 +1039,7 @@ send_response: + slapi_log_err (resp_log_level, + repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d replica=\"%s\": " ++ "conn=%" PRIu64 " op=%d replica=\"%s\": " + "Unable to acquire replica: error: %s%s\n", + connid, opid, + (replica ? slapi_sdn_get_dn(replica_get_root(replica)) : "unknown"), +@@ -1092,7 +1092,7 @@ send_response: + slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval); + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "multimaster_extop_StartNSDS50ReplicationRequest - " +- "conn=%" NSPRIu64 " op=%d repl=\"%s\": " ++ "conn=%" PRIu64 " op=%d repl=\"%s\": " + "%s: response=%d rc=%d\n", + connid, opid, repl_root, + is90 ? "StartNSDS90ReplicationRequest" : +diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c +index 667a529..bd856cb 100644 +--- a/ldap/servers/plugins/sync/sync_persist.c ++++ b/ldap/servers/plugins/sync/sync_persist.c +@@ -548,14 +548,14 @@ 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", ++ "sync_send_results - conn=%" PRIu64 " 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", ++ "sync_send_results - conn=%" PRIu64 " op=%d Could not acquire the connection - aborted\n", + connid, opid); + goto done; + } +@@ -566,7 +566,7 @@ sync_send_results( void *arg ) + /* Check for an abandoned operation */ + if ( op == NULL || slapi_is_operation_abandoned( op ) ) { + slapi_log_err(SLAPI_LOG_PLUGIN, SYNC_PLUGIN_SUBSYSTEM, +- "sync_send_results - conn=%" NSPRIu64 " op=%d Operation no longer active - terminating\n", ++ "sync_send_results - conn=%" PRIu64 " op=%d Operation no longer active - terminating\n", + connid, opid); + break; + } +diff --git a/ldap/servers/plugins/syntaxes/validate_task.c b/ldap/servers/plugins/syntaxes/validate_task.c +index eae2d2a..c051573 100644 +--- a/ldap/servers/plugins/syntaxes/validate_task.c ++++ b/ldap/servers/plugins/syntaxes/validate_task.c +@@ -201,12 +201,12 @@ syntax_validate_task_thread(void *arg) + slapi_pblock_destroy(search_pb); + + /* Log finished message. */ +- slapi_task_log_notice(task, "Syntax validate task complete. Found %" NSPRIu64 ++ slapi_task_log_notice(task, "Syntax validate task complete. Found %" PRIu64 + " invalid entries.\n", slapi_counter_get_value(td->invalid_entries)); +- slapi_task_log_status(task, "Syntax validate task complete. Found %" NSPRIu64 ++ slapi_task_log_status(task, "Syntax validate task complete. Found %" PRIu64 + " invalid entries.\n", slapi_counter_get_value(td->invalid_entries)); + slapi_log_err(SLAPI_LOG_ERR, SYNTAX_PLUGIN_SUBSYSTEM, "syntax_validate_task_thread - Complete." +- " Found %" NSPRIu64 " invalid entries.\n", ++ " Found %" PRIu64 " invalid entries.\n", + slapi_counter_get_value(td->invalid_entries)); + slapi_task_inc_progress(task); + +diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c +index 5e67e0a..54ebc31 100644 +--- a/ldap/servers/plugins/usn/usn.c ++++ b/ldap/servers/plugins/usn/usn.c +@@ -320,7 +320,7 @@ _usn_add_next_usn(Slapi_Entry *e, Slapi_Backend *be) + "--> _usn_add_next_usn\n"); + + /* add next USN to the entry; "be" contains the usn counter */ +- usn_berval.bv_val = slapi_ch_smprintf("%" NSPRIu64, ++ usn_berval.bv_val = slapi_ch_smprintf("%" PRIu64, + slapi_counter_get_value(be->be_usn_counter)); + usn_berval.bv_len = strlen(usn_berval.bv_val); + slapi_entry_attr_find(e, SLAPI_ATTR_ENTRYUSN, &attr); +@@ -360,7 +360,7 @@ _usn_mod_next_usn(LDAPMod ***mods, Slapi_Backend *be) + + /* add next USN to the mods; "be" contains the usn counter */ + usn_berval.bv_val = counter_buf; +- snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" PRIu64, + slapi_counter_get_value(be->be_usn_counter)); + usn_berval.bv_len = strlen(usn_berval.bv_val); + bvals[0] = &usn_berval; +@@ -681,7 +681,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* get a next USN counter from be_usn_counter; + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { +- snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" PRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { + snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); +@@ -704,7 +704,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + /* get a next USN counter from be_usn_counter; + * then minus 1 from it (except if be_usn_counter has value 0) */ + if (slapi_counter_get_value(be->be_usn_counter)) { +- snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, ++ snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" PRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + } else { + snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "-1"); +diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c +index 18ff8ce..0485006 100644 +--- a/ldap/servers/slapd/abandon.c ++++ b/ldap/servers/slapd/abandon.c +@@ -119,19 +119,19 @@ do_abandon( Slapi_PBlock *pb ) + } + + if ( 0 == pagedresults_free_one_msgid_nolock(pb->pb_conn, id) ) { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 + " op=%d ABANDON targetop=Simple Paged Results msgid=%d\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, id ); + } else if ( NULL == o ) { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ABANDON" + " targetop=NOTFOUND msgid=%d\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, id ); + } else if ( suppressed_by_plugin ) { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ABANDON" + " targetop=SUPPRESSED-BY-PLUGIN msgid=%d\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, id ); + } else { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ABANDON" + " targetop=%d msgid=%d nentries=%d etime=%ld\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, o->o_opid, id, + o->o_results.r.r_search.nentries, current_time() - o->o_time ); +diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c +index 1b994a0..9c4001e 100644 +--- a/ldap/servers/slapd/add.c ++++ b/ldap/servers/slapd/add.c +@@ -168,7 +168,7 @@ do_add( Slapi_PBlock *pb ) + if (( rc = slapi_entry_add_values( e, normtype, vals )) + != LDAP_SUCCESS ) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n", ++ "conn=%" PRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n", + pb->pb_conn->c_connid, operation->o_opid, + slapi_entry_get_dn_const(e), normtype ); + send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); +@@ -460,7 +460,7 @@ static void op_shared_add (Slapi_PBlock *pb) + + if ( !internal_op ) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\"%s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ADD dn=\"%s\"%s\n", + pb->pb_conn->c_connid, + operation->o_opid, + slapi_entry_get_dn_const(e), +diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c +index c787dd4..da1b586 100644 +--- a/ldap/servers/slapd/auth.c ++++ b/ldap/servers/slapd/auth.c +@@ -366,7 +366,7 @@ handle_bad_certificate (void* clientData, PRFileDesc *prfd) + char* subject = subject_of (clientCert); + char* issuer = issuer_of (clientCert); + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", ++ "conn=%" PRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", + conn->c_connid, errorCode, slapd_pr_strerror(errorCode), + subject ? escape_string( subject, sbuf ) : "NULL", + issuer ? escape_string( issuer, ibuf ) : "NULL" ); +@@ -402,7 +402,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + if ( (slapd_ssl_getChannelInfo (prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess ) { + PRErrorCode errorCode = PR_GetError(); + slapi_log_access (LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " SSL failed to obtain channel info; " ++ "conn=%" PRIu64 " SSL failed to obtain channel info; " + SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", + conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); + goto done; +@@ -411,7 +411,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + != SECSuccess) { + PRErrorCode errorCode = PR_GetError(); + slapi_log_access (LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " SSL failed to obtain cipher info; " ++ "conn=%" PRIu64 " SSL failed to obtain cipher info; " + SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", + conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); + goto done; +@@ -432,14 +432,14 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + + if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF ) { + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); +- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n", ++ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", + conn->c_connid, + sslversion, keySize, cipher ? cipher : "NULL" ); + goto done; + } + if (clientCert == NULL) { + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); +- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n", ++ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", + conn->c_connid, + sslversion, keySize, cipher ? cipher : "NULL" ); + } else { +@@ -448,7 +448,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " %s %i-bit %s; missing subject\n", ++ "conn=%" PRIu64 " %s %i-bit %s; missing subject\n", + conn->c_connid, + sslversion, keySize, cipher ? cipher : "NULL"); + goto done; +@@ -459,7 +459,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " %s %i-bit %s; client %s; issuer %s\n", ++ "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", + conn->c_connid, + sslversion, keySize, cipher ? cipher : "NULL", + subject ? escape_string( subject, sbuf ) : "NULL", +@@ -503,14 +503,14 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData) + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); + slapi_log_access (LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " %s client bound as %s\n", ++ "conn=%" PRIu64 " %s client bound as %s\n", + conn->c_connid, + sslversion, clientDN); + } else if (clientCert != NULL) { + (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); + slapi_log_access (LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " %s failed to map client " ++ "conn=%" PRIu64 " %s failed to map client " + "certificate to LDAP DN (%s)\n", + conn->c_connid, + sslversion, extraErrorMsg); +diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h +index a5fc540..0bb15e3 100644 +--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h ++++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h +@@ -28,21 +28,8 @@ + #endif + #endif + +-/* Required to get portable printf/scanf format macros */ +-#ifdef HAVE_INTTYPES_H +-#include +- +-/* NSPR uses the print macros a bit differently than ANSI C. We +- * need to use ll for a 64-bit integer, even when a long is 64-bit. +- */ +-#undef PRIu64 +-#define PRIu64 "llu" +-#undef PRI64 +-#define PRI64 "ll" +- +-#else +-#error Need to define portable format macros such as PRIu64 +-#endif /* HAVE_INTTYPES_H */ ++/* Provides our int types and platform specific requirements. */ ++#include + + /* A bunch of random system headers taken from all the source files, no source file should #include + any system headers now */ +@@ -162,11 +149,11 @@ typedef unsigned short u_int16_t; + #define DBVERSION_FILENAME "DBVERSION" + /* 0 here means to let the autotuning reset the value on first run */ + /* cache can't get any smaller than this (in bytes) */ +-#define MINCACHESIZE (size_t)512000 +-#define DEFAULT_CACHE_SIZE (size_t)0 ++#define MINCACHESIZE (uint64_t)512000 ++#define DEFAULT_CACHE_SIZE (uint64_t)0 + #define DEFAULT_CACHE_SIZE_STR "0" + #define DEFAULT_CACHE_ENTRIES -1 /* no limit */ +-#define DEFAULT_DNCACHE_SIZE (size_t)16777216 ++#define DEFAULT_DNCACHE_SIZE (uint64_t)16777216 + #define DEFAULT_DNCACHE_SIZE_STR "16777216" + #define DEFAULT_DNCACHE_MAXCOUNT -1 /* no limit */ + #define DEFAULT_DBCACHE_SIZE 33554432 +diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c +index ade2240..0f0cf3b 100644 +--- a/ldap/servers/slapd/back-ldbm/cache.c ++++ b/ldap/servers/slapd/back-ldbm/cache.c +@@ -649,7 +649,7 @@ void cache_set_max_size(struct cache *cache, size_t bytes, int type) + } + } + +-static void entrycache_set_max_size(struct cache *cache, size_t bytes) ++static void entrycache_set_max_size(struct cache *cache, uint64_t bytes) + { + struct backentry *eflush = NULL; + struct backentry *eflushtemp = NULL; +@@ -659,16 +659,17 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes) + * to happen. In that case, suppress this warning. + */ + if (bytes > 0) { +- slapi_log_err(SLAPI_LOG_WARNING, "entrycache_set_max_size", "Minimum cache size is %lu -- rounding up\n", MINCACHESIZE); ++ slapi_log_err(SLAPI_LOG_WARNING, "entrycache_set_max_size", "Minimum cache size is %"PRIu64" -- rounding up\n", MINCACHESIZE); + } + bytes = MINCACHESIZE; + } + cache_lock(cache); + cache->c_maxsize = bytes; +- LOG("entry cache size set to %lu\n", bytes); ++ LOG("entry cache size set to %"PRIu64"\n", bytes); + /* check for full cache, and clear out if necessary */ +- if (CACHE_FULL(cache)) ++ if (CACHE_FULL(cache)) { + eflush = entrycache_flush(cache); ++ } + while (eflush) + { + eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *); +@@ -686,12 +687,11 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes) + /* This may already have been called by one of the functions in + * ldbm_instance_config + */ +- if (! util_is_cachesize_sane(&bytes)) { +- slapi_log_err(SLAPI_LOG_WARNING, +- "entrycache_set_max_size", "Possible CONFIGURATION ERROR -- cachesize " +- "(%lu) may be configured to use more than the available " +- "physical memory.\n", bytes); ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ if (util_is_cachesize_sane(mi, &bytes) != UTIL_CACHESIZE_VALID) { ++ slapi_log_err(SLAPI_LOG_WARNING, "entrycache_set_max_size", "Cachesize (%"PRIu64") may use more than the available physical memory.\n", bytes); + } ++ spal_meminfo_destroy(mi); + } + + void cache_set_max_entries(struct cache *cache, long entries) +@@ -1597,7 +1597,7 @@ dn_same_id(const void *bdn, const void *k) + } + + static void +-dncache_set_max_size(struct cache *cache, size_t bytes) ++dncache_set_max_size(struct cache *cache, uint64_t bytes) + { + struct backdn *dnflush = NULL; + struct backdn *dnflushtemp = NULL; +@@ -1609,12 +1609,12 @@ dncache_set_max_size(struct cache *cache, size_t bytes) + if (bytes < MINCACHESIZE) { + bytes = MINCACHESIZE; + slapi_log_err(SLAPI_LOG_WARNING, +- "dncache_set_max_size", "Minimum cache size is %lu -- rounding up\n", ++ "dncache_set_max_size", "Minimum cache size is %"PRIu64" -- rounding up\n", + MINCACHESIZE); + } + cache_lock(cache); + cache->c_maxsize = bytes; +- LOG("entry cache size set to %lu\n", bytes); ++ LOG("entry cache size set to %"PRIu64"\n", bytes); + /* check for full cache, and clear out if necessary */ + if (CACHE_FULL(cache)) { + dnflush = dncache_flush(cache); +@@ -1636,12 +1636,12 @@ dncache_set_max_size(struct cache *cache, size_t bytes) + /* This may already have been called by one of the functions in + * ldbm_instance_config + */ +- if (! util_is_cachesize_sane(&bytes)) { +- slapi_log_err(SLAPI_LOG_WARNING, +- "dncache_set_max_size", "Possible CONFIGURATION ERROR -- cachesize " +- "(%lu) may be configured to use more than the available " +- "physical memory.\n", bytes); ++ ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ if (util_is_cachesize_sane(mi, &bytes) != UTIL_CACHESIZE_VALID) { ++ slapi_log_err(SLAPI_LOG_WARNING, "dncache_set_max_size", "Cachesize (%"PRIu64") may use more than the available physical memory.\n", bytes); + } ++ spal_meminfo_destroy(mi); + } + + /* remove a dn from the cache */ +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c +index 507a3cc..3c1fbb0 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.c ++++ b/ldap/servers/slapd/back-ldbm/dblayer.c +@@ -1386,14 +1386,16 @@ dblayer_start(struct ldbminfo *li, int dbmode) + + /* Sanity check on cache size on platforms which allow us to figure out + * the available phys mem */ +- if (!util_is_cachesize_sane(&(priv->dblayer_cachesize))) { ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ if (!util_is_cachesize_sane(mi, &(priv->dblayer_cachesize))) { + /* 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 (%lu bytes).\n", ++ "physical memory, decreased to the largest available size (%"PRIu64" bytes).\n", + priv->dblayer_cachesize); + li->li_dbcachesize = priv->dblayer_cachesize; + } ++ spal_meminfo_destroy(mi); + + /* fill in DB_ENV stuff from the common configuration */ + return_value = dblayer_make_env(&pEnv, li); +@@ -1690,9 +1692,6 @@ dblayer_start(struct ldbminfo *li, int dbmode) + * nsslapd-import-cache-autosize: 0 + * get the nsslapd-import-cachesize. + * Calculate the memory size left after allocating the import cache size. +- * If the size is less than the hard limit, it issues an error and quit. +- * If the size is greater than the hard limit and less than the soft limit, +- * it issues a warning, but continues the import task. + * + * Note: this function is called only if the import is executed as a stand + * alone command line (ldif2db). +@@ -1700,27 +1699,17 @@ dblayer_start(struct ldbminfo *li, int dbmode) + int + check_and_set_import_cache(struct ldbminfo *li) + { +- size_t import_pages = 0; +- size_t pagesize, pages, procpages, availpages; +- size_t soft_limit = 0; +- size_t hard_limit = 0; +- size_t page_delta = 0; ++ uint64_t import_cache = 0; + char s[64]; /* big enough to hold %ld */ ++ /* Get our platform memory values. */ ++ slapi_pal_meminfo *mi = spal_meminfo_get(); + +- if (util_info_sys_pages(&pagesize, &pages, &procpages, &availpages) != 0 || 0 == pagesize || 0 == pages) { +- slapi_log_err(SLAPI_LOG_ERR, "check_and_set_import_cache", +- "Failed to get pagesize: %ld or pages: %ld\n", +- pagesize, pages); ++ if (mi == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, "check_and_set_import_cache", "Failed to get system memory infomation\n"); + return ENOENT; + } +- slapi_log_err(SLAPI_LOG_INFO, "check_and_set_import_cache", +- "pagesize: %ld, pages: %ld, procpages: %ld\n", +- pagesize, pages, procpages); ++ slapi_log_err(SLAPI_LOG_INFO, "check_and_set_import_cache", "pagesize: %"PRIu64", available bytes %"PRIu64", process usage %"PRIu64" \n", mi->pagesize_bytes, mi->system_available_bytes, mi->process_consumed_bytes); + +- /* Soft limit: pages equivalent to 1GB (defined in dblayer.h) */ +- soft_limit = (DBLAYER_IMPORTCACHESIZE_SL*1024) / (pagesize/1024); +- /* Hard limit: pages equivalent to 100MB (defined in dblayer.h) */ +- hard_limit = (DBLAYER_IMPORTCACHESIZE_HL*1024) / (pagesize/1024); + /* + * default behavior for ldif2db import cache, + * nsslapd-import-cache-autosize==-1, +@@ -1741,48 +1730,29 @@ check_and_set_import_cache(struct ldbminfo *li) + + if (li->li_import_cache_autosize == 0) { + /* user specified importCache */ +- import_pages = li->li_import_cachesize / pagesize; ++ import_cache = li->li_import_cachesize; + + } else { + /* autosizing importCache */ + /* ./125 instead of ./100 is for adjusting the BDB overhead. */ +-#ifdef LINUX +- /* On linux, availpages is correct so we should use it! */ +- import_pages = (li->li_import_cache_autosize * availpages) / 125; +-#else +- import_pages = (li->li_import_cache_autosize * pages) / 125; +-#endif ++ import_cache = (li->li_import_cache_autosize * mi->system_available_bytes) / 125; + } + +- page_delta = pages - import_pages; +- if (page_delta < hard_limit) { +- slapi_log_err(SLAPI_LOG_ERR, +- "check_and_set_import_cache", "After allocating import cache %ldKB, " +- "the available memory is %ldKB, " +- "which is less than the hard limit %ldKB. " +- "Please decrease the import cache size and rerun import.\n", +- import_pages*(pagesize/1024), page_delta*(pagesize/1024), +- hard_limit*(pagesize/1024)); ++ if (util_is_cachesize_sane(mi, &import_cache) == UTIL_CACHESIZE_ERROR) { ++ ++ slapi_log_err(SLAPI_LOG_INFO, "check_and_set_import_cache", "Import failed to run: unable to validate system memory limits.\n"); ++ spal_meminfo_destroy(mi); + return ENOMEM; + } +- if (page_delta < soft_limit) { +- slapi_log_err(SLAPI_LOG_WARNING, +- "check_and_set_import_cache", "After allocating import cache %ldKB, " +- "the available memory is %ldKB, " +- "which is less than the soft limit %ldKB. " +- "You may want to decrease the import cache size and " +- "rerun import.\n", +- import_pages*(pagesize/1024), page_delta*(pagesize/1024), +- soft_limit*(pagesize/1024)); +- } + +- slapi_log_err(SLAPI_LOG_INFO, "check_and_set_import_cache", "Import allocates %ldKB import cache.\n", +- import_pages*(pagesize/1024)); +- if (li->li_import_cache_autosize > 0) { /* import cache autosizing */ ++ slapi_log_err(SLAPI_LOG_INFO, "check_and_set_import_cache", "Import allocates %"PRIu64"KB import cache.\n", import_cache / 1024); ++ if (li->li_import_cache_autosize > 0) { ++ /* import cache autosizing */ + /* set the calculated import cache size to the config */ +- sprintf(s, "%lu", (unsigned long)(import_pages * pagesize)); ++ sprintf(s, "%"PRIu64, import_cache); + ldbm_config_internal_set(li, CONFIG_IMPORT_CACHESIZE, s); + } ++ spal_meminfo_destroy(mi); + return 0; + } + +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h +index e4307fc..816c943 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.h ++++ b/ldap/servers/slapd/back-ldbm/dblayer.h +@@ -68,14 +68,6 @@ + #define DB_REGION_NAME 25 /* DB: named regions, no backing file. */ + #endif + +-/* Used in check_and_set_import_cache */ +-/* After allocating the import cache, free memory must be left more than +- * the hard limit to run import. */ +-/* If the free memory size left is greater than hard limit and less than +- * soft limit, the import utility issues a warning, but it runs */ +-#define DBLAYER_IMPORTCACHESIZE_HL 100 /* import cache hard limit 100MB */ +-#define DBLAYER_IMPORTCACHESIZE_SL 1024 /* import cache soft limit 1GB */ +- + struct dblayer_private_env { + DB_ENV *dblayer_DB_ENV; + Slapi_RWLock * dblayer_env_lock; +diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c +index 087103b..ab32e0a 100644 +--- a/ldap/servers/slapd/back-ldbm/import-threads.c ++++ b/ldap/servers/slapd/back-ldbm/import-threads.c +@@ -3979,7 +3979,7 @@ _get_import_entryusn(ImportJob *job, Slapi_Value **usn_value) + * Use the counter which stores the old DB's + * next entryusn. */ + PR_snprintf(counter_buf, sizeof(counter_buf), +- "%" NSPRIu64, slapi_counter_get_value(be->be_usn_counter)); ++ "%" PRIu64, slapi_counter_get_value(be->be_usn_counter)); + } else { + /* import_init value is digit. + * Initialize the entryusn values with the digit */ +diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c +index d0cef1a..7161bac 100644 +--- a/ldap/servers/slapd/back-ldbm/import.c ++++ b/ldap/servers/slapd/back-ldbm/import.c +@@ -84,17 +84,19 @@ static int import_fifo_init(ImportJob *job) + int import_fifo_validate_capacity_or_expand(ImportJob *job, size_t entrysize) { + int result = 1; + /* We shoot for four times as much to start with. */ +- size_t request = entrysize * 4; +- int sane = 0; ++ uint64_t request = entrysize * 4; ++ util_cachesize_result sane; + + if (entrysize > job->fifo.bsize) { + /* Check the amount of memory on the system */ +- sane = util_is_cachesize_sane(&request); +- if (!sane && entrysize <= request) { ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ sane = util_is_cachesize_sane(mi, &request); ++ spal_meminfo_destroy(mi); ++ if (sane == UTIL_CACHESIZE_REDUCED && entrysize <= request) { + /* Did the amount cachesize set still exceed entrysize? It'll do ... */ + job->fifo.bsize = request; + result = 0; +- } else if (!sane) { ++ } else if (sane != UTIL_CACHESIZE_VALID) { + /* Can't allocate! No!!! */ + result = 1; + } else { +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c +index dfe7a13..d5120d3 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c +@@ -403,8 +403,8 @@ static int ldbm_config_dbcachesize_set(void *arg, void *value, char *errorbuf, i + { + struct ldbminfo *li = (struct ldbminfo *) arg; + int retval = LDAP_SUCCESS; +- size_t val = (size_t)value; +- size_t delta = (size_t)value; ++ uint64_t val = (size_t)value; ++ uint64_t delta = (size_t)value; + + /* There is an error here. We check the new val against our current mem-alloc + * Issue is that we already are using system pages, so while our value *might* +@@ -430,7 +430,13 @@ static int ldbm_config_dbcachesize_set(void *arg, void *value, char *errorbuf, i + val = DBDEFMINSIZ; + } else if (val > li->li_dbcachesize) { + delta = val - li->li_dbcachesize; +- if (!util_is_cachesize_sane(&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: nsslapd-dbcachesize value is too large."); + slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_dbcachesize_set", + "nsslapd-dbcachesize value is too large.\n"); +@@ -1086,7 +1092,7 @@ static int ldbm_config_db_cache_set(void *arg, void *value, char *errorbuf, int + struct ldbminfo *li = (struct ldbminfo *) arg; + int retval = LDAP_SUCCESS; + int val = ((uintptr_t)value); +- size_t delta = 0; ++ uint64_t delta = 0; + + /* There is an error here. We check the new val against our current mem-alloc + * Issue is that we already are using system pages, so while our value *might* +@@ -1101,7 +1107,13 @@ static int ldbm_config_db_cache_set(void *arg, void *value, char *errorbuf, int + if (apply) { + if (val > li->li_dblayer_private->dblayer_cache_config) { + delta = val - li->li_dblayer_private->dblayer_cache_config; +- if (!util_is_cachesize_sane(&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: db cachesize value is too large"); + slapi_log_err(SLAPI_LOG_ERR,"ldbm_config_db_cache_set", "db cachesize value is too large.\n"); + return LDAP_UNWILLING_TO_PERFORM; +@@ -1219,7 +1231,7 @@ static int ldbm_config_import_cachesize_set(void *arg, void *value, char *errorb + { + struct ldbminfo *li = (struct ldbminfo *)arg; + size_t val = (size_t)value; +- size_t delta = (size_t)value; ++ uint64_t delta = (size_t)value; + /* There is an error here. We check the new val against our current mem-alloc + * Issue is that we already are using system pages, so while our value *might* + * be valid, we may reject it here due to the current procs page usage. +@@ -1232,7 +1244,13 @@ static int ldbm_config_import_cachesize_set(void *arg, void *value, char *errorb + if (apply){ + if (val > li->li_import_cachesize) { + delta = val - li->li_import_cachesize; +- if (!util_is_cachesize_sane(&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: import cachesize value is too large."); + slapi_log_err(SLAPI_LOG_ERR,"ldbm_config_import_cachesize_set", + "Import cachesize value is too large.\n"); +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +index 92d982e..0b0b37e 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c +@@ -107,7 +107,7 @@ ldbm_back_delete( Slapi_PBlock *pb ) + + if (pb->pb_conn) + { +- slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_delete", "Enter conn=%" NSPRIu64 " op=%d\n", ++ slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_delete", "Enter conn=%" PRIu64 " op=%d\n", + pb->pb_conn->c_connid, operation->o_opid); + } + +@@ -1493,7 +1493,7 @@ diskfull_return: + slapi_sdn_done(&parentsdn); + if (pb->pb_conn) + { +- slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" NSPRIu64 " op=%d\n", ++ slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_delete", "leave conn=%" PRIu64 " op=%d\n", + pb->pb_conn->c_connid, operation->o_opid); + } + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c +index e03954d..62cdbc3 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c +@@ -92,7 +92,7 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in + ldbm_instance *inst = (ldbm_instance *) arg; + int retval = LDAP_SUCCESS; + size_t val = (size_t) value; +- size_t delta = 0; ++ uint64_t delta = 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,7 +108,13 @@ 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; +- if (!util_is_cachesize_sane(&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"); + return LDAP_UNWILLING_TO_PERFORM; +@@ -134,7 +140,7 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf, + ldbm_instance *inst = (ldbm_instance *) arg; + int retval = LDAP_SUCCESS; + size_t val = (size_t)value; +- size_t delta = 0; ++ uint64_t delta = 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 +@@ -150,7 +156,13 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf, + if (apply) { + if (val > inst->inst_dncache.c_maxsize) { + delta = val - inst->inst_dncache.c_maxsize; +- if (!util_is_cachesize_sane(&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: dncachememsize value is too large."); + slapi_log_err(SLAPI_LOG_ERR,"ldbm_instance_config_dncachememsize_set", +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +index a78d850..533273b 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +@@ -142,7 +142,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) + + if (pb->pb_conn) + { +- slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_modrdn", "enter conn=%" NSPRIu64 " op=%d\n", ++ slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_modrdn", "enter conn=%" PRIu64 " op=%d\n", + pb->pb_conn->c_connid, operation->o_opid); + } + +@@ -1539,7 +1539,7 @@ common_return: + if (pb->pb_conn) + { + slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_modrdn", +- "leave conn=%" NSPRIu64 " op=%d\n", ++ "leave conn=%" PRIu64 " op=%d\n", + pb->pb_conn->c_connid, operation->o_opid); + } + return retval; +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c +index a6c3b74..cfb0d6b 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c +@@ -407,7 +407,7 @@ ldbm_back_search( Slapi_PBlock *pb ) + slapi_pblock_get(pb, SLAPI_OPERATION_ID, &op_id); + + slapi_log_err(SLAPI_LOG_WARNING, +- "ldbm_back_search", "Sort control ignored for conn=%" NSPRIu64 " op=%d\n", ++ "ldbm_back_search", "Sort control ignored for conn=%" PRIu64 " op=%d\n", + conn_id, op_id); + } + } else { +@@ -442,7 +442,7 @@ ldbm_back_search( Slapi_PBlock *pb ) + slapi_pblock_get(pb, SLAPI_OPERATION_ID, &op_id); + + slapi_log_err(SLAPI_LOG_WARNING, +- "ldbm_back_search", "VLV control ignored for conn=%" NSPRIu64 " op=%d\n", ++ "ldbm_back_search", "VLV control ignored for conn=%" PRIu64 " op=%d\n", + conn_id, op_id); + } + +diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c +index 5268087..7192b3a 100644 +--- a/ldap/servers/slapd/back-ldbm/misc.c ++++ b/ldap/servers/slapd/back-ldbm/misc.c +@@ -54,7 +54,7 @@ void ldbm_log_access_message(Slapi_PBlock *pblock,char *string) + return; + } + operation_id = operation->o_opid; +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d %s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d %s\n", + connection_id, operation_id, string); + } + +diff --git a/ldap/servers/slapd/back-ldbm/monitor.c b/ldap/servers/slapd/back-ldbm/monitor.c +index 757792b..c58b069 100644 +--- a/ldap/servers/slapd/back-ldbm/monitor.c ++++ b/ldap/servers/slapd/back-ldbm/monitor.c +@@ -101,9 +101,9 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + /* fetch cache statistics */ + cache_get_stats(&(inst->inst_dncache), &hits, &tries, + &nentries, &maxentries, &size, &maxsize); +- sprintf(buf, "%" NSPRIu64, hits); ++ sprintf(buf, "%" PRIu64, hits); + MSET("dnCacheHits"); +- sprintf(buf, "%" NSPRIu64, tries); ++ sprintf(buf, "%" PRIu64, tries); + MSET("dnCacheTries"); + sprintf(buf, "%lu", (unsigned long)(100.0*(double)hits / (double)(tries > 0 ? tries : 1))); + MSET("dnCacheHitRatio"); +@@ -119,11 +119,11 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + /* normalized dn cache stats */ + if(ndn_cache_started()){ + ndn_cache_get_stats(&hits, &tries, &size, &maxsize, &count); +- sprintf(buf, "%" NSPRIu64, tries); ++ sprintf(buf, "%" PRIu64, tries); + MSET("normalizedDnCacheTries"); +- sprintf(buf, "%" NSPRIu64, hits); ++ sprintf(buf, "%" PRIu64, hits); + MSET("normalizedDnCacheHits"); +- sprintf(buf, "%" NSPRIu64, (tries - hits)); ++ sprintf(buf, "%" PRIu64, (tries - hits)); + MSET("normalizedDnCacheMisses"); + sprintf(buf, "%lu", (unsigned long)(100.0*(double)hits / (double)(tries > 0 ? tries : 1))); + MSET("normalizedDnCacheHitRatio"); +diff --git a/ldap/servers/slapd/back-ldbm/perfctrs.h b/ldap/servers/slapd/back-ldbm/perfctrs.h +index 57be1d1..64c79e1 100644 +--- a/ldap/servers/slapd/back-ldbm/perfctrs.h ++++ b/ldap/servers/slapd/back-ldbm/perfctrs.h +@@ -11,7 +11,7 @@ + # include + #endif + +-#include ++#include + + /* Structure definition for performance data */ + /* This stuff goes in shared memory, so make sure the packing is consistent */ +diff --git a/ldap/servers/slapd/back-ldbm/start.c b/ldap/servers/slapd/back-ldbm/start.c +index 1ae9858..a207bd8 100644 +--- a/ldap/servers/slapd/back-ldbm/start.c ++++ b/ldap/servers/slapd/back-ldbm/start.c +@@ -32,34 +32,25 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + Object *inst_obj = NULL; + ldbm_instance *inst = NULL; + /* size_t is a platform unsigned int, IE uint64_t */ +- size_t total_cache_size = 0; +- size_t pagesize = 0; +- size_t pages = 0; +- size_t procpages __attribute__((unused)) = 0; +- size_t availpages = 0; +- size_t cache_size_to_configure = 0; +- size_t zone_pages = 0; +- size_t db_pages = 0; +- size_t entry_pages = 0; +- size_t import_pages = 0; +- size_t zone_size = 0; +- size_t import_size = 0; +- size_t cache_size = 0; +- size_t db_size = 0; ++ uint64_t total_cache_size = 0; ++ uint64_t entry_size = 0; ++ uint64_t zone_size = 0; ++ uint64_t import_size = 0; ++ uint64_t cache_size = 0; ++ uint64_t db_size = 0; + /* For clamping the autotune value to a 64Mb boundary */ +- size_t clamp_pages = 0; +- size_t clamp_div = 0; +- size_t clamp_mod = 0; ++ uint64_t clamp_div = 0; + /* Backend count */ +- size_t backend_count = 0; ++ uint64_t backend_count = 0; + + int_fast32_t autosize_percentage = 0; + int_fast32_t autosize_db_percentage_split = 0; + int_fast32_t import_percentage = 0; +- int32_t issane = 0; ++ util_cachesize_result issane; + char *msg = ""; /* This will be set by one of the two cache sizing paths below. */ + char size_to_str[32]; /* big enough to hold %ld */ + ++ + /* == Begin autotune == */ + + /* +@@ -120,42 +111,34 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + return SLAPI_FAIL_GENERAL; + } + +- if (util_info_sys_pages(&pagesize, &pages, &procpages, &availpages) != 0) { ++ /* Get our platform memory values. */ ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ if (mi == NULL) { + slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "Unable to determine system page limits\n"); + return SLAPI_FAIL_GENERAL; + } + +- if (pagesize == 0) { +- /* If this happens, we are in a very bad state indeed... */ +- slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_start", "Unable to determine system page size\n"); +- return SLAPI_FAIL_GENERAL; +- } +- + /* calculate the needed values */ +- zone_pages = (autosize_percentage * pages) / 100; +- zone_size = zone_pages * pagesize; ++ zone_size = (autosize_percentage * mi->system_total_bytes) / 100; + /* This is how much we "might" use, lets check it's sane. */ + /* In the case it is not, this will *reduce* the allocation */ +- issane = util_is_cachesize_sane(&zone_size); +- if (!issane) { ++ issane = util_is_cachesize_sane(mi, &zone_size); ++ if (issane == UTIL_CACHESIZE_REDUCED) { + slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "Your autosized cache values have been reduced. Likely your nsslapd-cache-autosize percentage is too high.\n"); + slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "%s", msg); + } + /* It's valid, lets divide it up and set according to user prefs */ +- zone_pages = zone_size / pagesize; +- db_pages = (autosize_db_percentage_split * zone_pages) / 100; ++ 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) */ +- if ((db_pages * pagesize) > (512 * MEGABYTE)) { +- db_pages = (512 * MEGABYTE) / pagesize; ++ if (db_size > (512 * MEGABYTE)) { ++ db_size = (512 * MEGABYTE); + } + + if (backend_count > 0 ) { + /* Number of entry cache pages per backend. */ +- entry_pages = (zone_pages - db_pages) / backend_count; ++ entry_size = (zone_size - db_size) / backend_count; + /* Now, clamp this value to a 64mb boundary. */ +- /* How many pages are in 64mb? */ +- clamp_pages = (64 * MEGABYTE) / pagesize; + /* Now divide the entry pages by this, and also mod. If mod != 0, we need + * to add 1 to the diveded number. This should give us: + * 510 * 1024 * 1024 == 510MB +@@ -166,17 +149,15 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + * 130560 % 16384 = 15872 which is != 0 + * therfore 7 + 1, aka 8 * 16384 = 131072 pages = 536870912 bytes = 512MB. + */ +- clamp_div = entry_pages / clamp_pages; +- clamp_mod = entry_pages % clamp_pages; +- if (clamp_mod != 0) { +- /* If we want to clamp down, remove this line. This would change the above from 510mb -> 448mb. */ +- clamp_div += 1; +- entry_pages = clamp_div * clamp_pages; ++ if (entry_size % (64 * MEGABYTE) != 0) { ++ /* If we want to clamp down, remove the "+1". This would change the above from 510mb -> 448mb. */ ++ clamp_div = (entry_size / (64 * MEGABYTE)) + 1; ++ entry_size = clamp_div * (64 * MEGABYTE); + } + } + +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "found %luk physical memory\n", pages*(pagesize/1024)); +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "found %luk avaliable\n", zone_pages*(pagesize/1024)); ++ 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); + + /* 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 +@@ -191,13 +172,12 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + + /* First, check the dbcache */ + if (li->li_dbcachesize == 0 || li->li_cache_autosize > 0) { +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: db cache: %luk\n", db_pages*(pagesize/1024)); +- cache_size_to_configure = (unsigned long)(db_pages * pagesize); +- if (cache_size_to_configure < (500 * MEGABYTE)) { +- cache_size_to_configure = (unsigned long)((db_pages * pagesize) / 1.25); ++ slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: db cache: %luk\n", db_size / 1024); ++ if (db_size < (500 * MEGABYTE)) { ++ db_size = db_size / 1.25; + } + /* Have to set this value through text. */ +- sprintf(size_to_str, "%lu", cache_size_to_configure); ++ sprintf(size_to_str, "%" PRIu64 , db_size); + ldbm_config_internal_set(li, CONFIG_DBCACHESIZE, size_to_str); + } + total_cache_size += li->li_dbcachesize; +@@ -205,7 +185,7 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + /* For each backend */ + /* apply the appropriate cache size if 0 */ + if (backend_count > 0 ) { +- li->li_cache_autosize_ec = (unsigned long)entry_pages * pagesize; ++ li->li_cache_autosize_ec = entry_size; + } + + for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj; +@@ -220,7 +200,7 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + * it's highly unlikely. + */ + if (cache_size == 0 || cache_size == MINCACHESIZE || li->li_cache_autosize > 0) { +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: %s entry cache (%lu total): %luk\n", inst->inst_name, backend_count, entry_pages*(pagesize/1024)); ++ slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: %s entry cache (%lu total): %luk\n", inst->inst_name, backend_count, entry_size / 1024); + cache_set_max_entries(&(inst->inst_cache), -1); + cache_set_max_size(&(inst->inst_cache), li->li_cache_autosize_ec, CACHE_TYPE_ENTRY); + } +@@ -229,8 +209,8 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + db_size = dblayer_get_id2entry_size(inst); + if (cache_size < db_size) { + slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", +- "%s: entry cache size %lu B is " +- "less than db size %lu B; " ++ "%s: entry cache size %"PRIu64" B is " ++ "less than db size %"PRIu64" B; " + "We recommend to increase the entry cache size " + "nsslapd-cachememsize.\n", + inst->inst_name, cache_size, db_size); +@@ -244,37 +224,36 @@ ldbm_back_start_autotune(struct ldbminfo *li) { + /* autosizing importCache */ + if (li->li_import_cache_autosize > 0) { + /* Use import percentage here, as it's been corrected for -1 behaviour */ +- import_pages = (import_percentage * pages) / 100; +- import_size = import_pages * pagesize; +- issane = util_is_cachesize_sane(&import_size); +- if (!issane) { ++ import_size = (import_percentage * mi->system_total_bytes) / 100; ++ issane = util_is_cachesize_sane(mi, &import_size); ++ if (issane == UTIL_CACHESIZE_REDUCED) { + slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_start", "Your autosized import cache values have been reduced. Likely your nsslapd-import-cache-autosize percentage is too high.\n"); + } + /* We just accept the reduced allocation here. */ +- import_pages = import_size / pagesize; +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: import cache: %luk\n", +- import_pages*(pagesize/1024)); ++ slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "cache autosizing: import cache: %"PRIu64"k\n", import_size / 1024); + +- sprintf(size_to_str, "%lu", (unsigned long)(import_pages * pagesize)); ++ sprintf(size_to_str, "%"PRIu64, import_size); + ldbm_config_internal_set(li, CONFIG_IMPORT_CACHESIZE, size_to_str); + } + + /* Finally, lets check that the total result is sane. */ +- slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "total cache size: %lu B; \n", total_cache_size); ++ slapi_log_err(SLAPI_LOG_NOTICE, "ldbm_back_start", "total cache size: %"PRIu64" B; \n", total_cache_size); + +- issane = util_is_cachesize_sane(&total_cache_size); +- if (!issane) { ++ issane = util_is_cachesize_sane(mi, &total_cache_size); ++ if (issane != UTIL_CACHESIZE_VALID) { + /* Right, it's time to panic */ + 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_WARNING, "ldbm_back_start", "Total entry cache size: %"PRIu64" B; dbcache size: %"PRIu64" B; available memory size: %"PRIu64" B; \n", ++ total_cache_size, (uint64_t)li->li_dbcachesize, mi->system_available_bytes + ); + 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; */ + } + ++ spal_meminfo_destroy(mi); ++ + /* == End autotune == */ + return 0; + } +diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c +index f83df7d..648a0f9 100644 +--- a/ldap/servers/slapd/bind.c ++++ b/ldap/servers/slapd/bind.c +@@ -853,25 +853,25 @@ log_bind_access ( + { + if (method == LDAP_AUTH_SASL && saslmech && msg) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d BIND dn=\"%s\" " ++ "conn=%" PRIu64 " op=%d BIND dn=\"%s\" " + "method=sasl version=%d mech=%s, %s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, + version, saslmech, msg ); + } else if (method == LDAP_AUTH_SASL && saslmech) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d BIND dn=\"%s\" " ++ "conn=%" PRIu64 " op=%d BIND dn=\"%s\" " + "method=sasl version=%d mech=%s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, + version, saslmech ); + } else if (msg) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d BIND dn=\"%s\" " ++ "conn=%" PRIu64 " op=%d BIND dn=\"%s\" " + "method=%" BERTAG_T " version=%d, %s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, + method, version, msg ); + } else { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d BIND dn=\"%s\" " ++ "conn=%" PRIu64 " op=%d BIND dn=\"%s\" " + "method=%" BERTAG_T " version=%d\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, + method, version ); +diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c +index 07ded98..3c03053 100644 +--- a/ldap/servers/slapd/compare.c ++++ b/ldap/servers/slapd/compare.c +@@ -111,7 +111,7 @@ do_compare( Slapi_PBlock *pb ) + rawdn, ava.ava_type, 0 ); + + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d CMP dn=\"%s\" attr=\"%s\"\n", ++ "conn=%" PRIu64 " op=%d CMP dn=\"%s\" attr=\"%s\"\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, ava.ava_type ); + + /* +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index 7c83c66..359b59a 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -411,7 +411,7 @@ connection_reset(Connection* conn, int ns, PRNetAddr * from, int fromLen, int is + + /* log useful stuff to our access log */ + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " fd=%d slot=%d %sconnection from %s to %s\n", ++ "conn=%" PRIu64 " fd=%d slot=%d %sconnection from %s to %s\n", + conn->c_connid, conn->c_sd, ns, pTmp, str_ip, str_destip ); + + /* initialize the remaining connection fields */ +@@ -511,7 +511,7 @@ connection_need_new_password(const Connection *conn, const Operation *op, Slapi_ + op->o_tag != LDAP_REQ_ABANDON && op->o_tag != LDAP_REQ_EXTENDED) + { + slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0); +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d %s\n", ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d %s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, + "UNPROCESSED OPERATION - need new password" ); + send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, +@@ -562,7 +562,7 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb) + (op->o_tag != LDAP_REQ_EXTENDED) && (op->o_tag != LDAP_REQ_UNBIND) && + (op->o_tag != LDAP_REQ_ABANDON)) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d UNPROCESSED OPERATION" ++ "conn=%" PRIu64 " op=%d UNPROCESSED OPERATION" + " - Insufficient SSF (local_ssf=%d sasl_ssf=%d ssl_ssf=%d)\n", + conn->c_connid, op->o_opid, conn->c_local_ssf, + conn->c_sasl_ssf, conn->c_ssl_ssf ); +@@ -591,7 +591,7 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb) + (op->o_tag != LDAP_REQ_ABANDON) && (op->o_tag != LDAP_REQ_SEARCH)))) + { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d UNPROCESSED OPERATION" ++ "conn=%" PRIu64 " op=%d UNPROCESSED OPERATION" + " - Anonymous access not allowed\n", + conn->c_connid, op->o_opid ); + +@@ -650,7 +650,7 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb) + int ret = setsockopt(conn->c_sd,IPPROTO_TCP,TCP_CORK,&i,sizeof(i)); + if (ret < 0) { + slapi_log_err(SLAPI_LOG_ERR, "connection_dispatch_operation", +- "Failed to set TCP_CORK on connection %" NSPRIu64 "\n",conn->c_connid); ++ "Failed to set TCP_CORK on connection %" PRIu64 "\n",conn->c_connid); + } + pop_cork = 1; + } +@@ -664,7 +664,7 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb) + int ret = setsockopt(conn->c_sd,IPPROTO_TCP,TCP_CORK,&i,sizeof(i)); + if (ret < 0) { + slapi_log_err(SLAPI_LOG_ERR, "connection_dispatch_operation", +- "Failed to clear TCP_CORK on connection %" NSPRIu64 "\n",conn->c_connid); ++ "Failed to clear TCP_CORK on connection %" PRIu64 "\n",conn->c_connid); + } + } + #endif +@@ -690,7 +690,7 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb) + + default: + slapi_log_err(SLAPI_LOG_ERR, +- "connection_dispatch_operation", "Ignoring unknown LDAP request (conn=%" NSPRIu64 ", tag=0x%lx)\n", ++ "connection_dispatch_operation", "Ignoring unknown LDAP request (conn=%" PRIu64 ", tag=0x%lx)\n", + conn->c_connid, op->o_tag); + break; + } +@@ -702,7 +702,7 @@ int connection_release_nolock_ext (Connection *conn, int release_only) + if (conn->c_refcnt <= 0) + { + slapi_log_err(SLAPI_LOG_ERR, "connection_release_nolock_ext", +- "conn=%" NSPRIu64 " fd=%d Attempt to release connection that is not acquired\n", ++ "conn=%" PRIu64 " fd=%d Attempt to release connection that is not acquired\n", + conn->c_connid, conn->c_sd); + PR_ASSERT (PR_FALSE); + return -1; +@@ -734,7 +734,7 @@ int connection_acquire_nolock_ext (Connection *conn, int allow_when_closing) + { + /* This may happen while other threads are still working on this connection */ + slapi_log_err(SLAPI_LOG_ERR, "connection_acquire_nolock_ext", +- "conn=%" NSPRIu64 " fd=%d Attempt to acquire connection in the closing state\n", ++ "conn=%" PRIu64 " fd=%d Attempt to acquire connection in the closing state\n", + conn->c_connid, conn->c_sd); + return -1; + } +@@ -1070,7 +1070,7 @@ get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp, + syserr = errno; + /* Bad stuff happened, like the client sent us some junk */ + slapi_log_err(SLAPI_LOG_CONNS, "get_next_from_buffer", +- "ber_get_next failed for connection %" NSPRIu64 "\n", conn->c_connid); ++ "ber_get_next failed for connection %" PRIu64 "\n", conn->c_connid); + /* reset private buffer */ + conn->c_private->c_buffer_bytes = conn->c_private->c_buffer_offset = 0; + +@@ -1232,7 +1232,7 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + /* Otherwise we loop, unless we exceeded the ioblock timeout */ + if (waits_done > ioblocktimeout_waits) { + slapi_log_err(SLAPI_LOG_CONNS,"connection_read_operation", +- "ioblocktimeout expired on connection %" NSPRIu64 "\n", conn->c_connid); ++ "ioblocktimeout expired on connection %" PRIu64 "\n", conn->c_connid); + disconnect_server_nomutex( conn, conn->c_connid, -1, + SLAPD_DISCONNECT_IO_TIMEOUT, 0 ); + ret = CONN_DONE; +@@ -1253,19 +1253,19 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + err = PR_GetError(); + syserr = PR_GetOSError(); + slapi_log_err(SLAPI_LOG_ERR, "connection_read_operation", +- "PR_Poll for connection %" NSPRIu64 " returns %d (%s)\n", conn->c_connid, err, slapd_pr_strerror( err ) ); ++ "PR_Poll for connection %" PRIu64 " returns %d (%s)\n", conn->c_connid, err, slapd_pr_strerror( err ) ); + /* If this happens we should close the connection */ + disconnect_server_nomutex( conn, conn->c_connid, -1, err, syserr ); + ret = CONN_DONE; + goto done; + } + slapi_log_err(SLAPI_LOG_CONNS, +- "connection_read_operation", "connection %" NSPRIu64 " waited %d times for read to be ready\n", conn->c_connid, waits_done); ++ "connection_read_operation", "connection %" PRIu64 " waited %d times for read to be ready\n", conn->c_connid, waits_done); + } else { + /* Some other error, typically meaning bad stuff */ + syserr = PR_GetOSError(); + slapi_log_err(SLAPI_LOG_CONNS, "connection_read_operation", +- "PR_Recv for connection %" NSPRIu64 " returns %d (%s)\n", conn->c_connid, err, slapd_pr_strerror( err ) ); ++ "PR_Recv for connection %" PRIu64 " returns %d (%s)\n", conn->c_connid, err, slapd_pr_strerror( err ) ); + /* If this happens we should close the connection */ + disconnect_server_nomutex( conn, conn->c_connid, -1, err, syserr ); + ret = CONN_DONE; +@@ -1286,7 +1286,7 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + } + } + slapi_log_err(SLAPI_LOG_CONNS, +- "connection_read_operation", "connection %" NSPRIu64 " read %d bytes\n", conn->c_connid, ret); ++ "connection_read_operation", "connection %" PRIu64 " read %d bytes\n", conn->c_connid, ret); + + new_operation = 0; + ret = CONN_FOUND_WORK_TO_DO; +@@ -1307,7 +1307,7 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + * We received a non-LDAP message. Log and close connection. + */ + slapi_log_err(SLAPI_LOG_ERR, +- "connection_read_operation", "conn=%" NSPRIu64 " received a non-LDAP message (tag 0x%lx, expected 0x%lx)\n", ++ "connection_read_operation", "conn=%" PRIu64 " received a non-LDAP message (tag 0x%lx, expected 0x%lx)\n", + conn->c_connid, *tag, LDAP_TAG_MESSAGE ); + disconnect_server_nomutex( conn, conn->c_connid, -1, + SLAPD_DISCONNECT_BAD_BER_TAG, EPROTO ); +@@ -1319,7 +1319,7 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + != LDAP_TAG_MSGID ) { + /* log, close and send error */ + slapi_log_err(SLAPI_LOG_ERR, +- "connection_read_operation", "conn=%" NSPRIu64 " unable to read tag for incoming request\n", conn->c_connid); ++ "connection_read_operation", "conn=%" PRIu64 " unable to read tag for incoming request\n", conn->c_connid); + disconnect_server_nomutex( conn, conn->c_connid, -1, SLAPD_DISCONNECT_BAD_BER_TAG, EPROTO ); + ret = CONN_DONE; + goto done; +@@ -1337,7 +1337,7 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i + case LDAP_TAG_LDAPDN: /* optional username, for CLDAP */ + /* log, close and send error */ + slapi_log_err(SLAPI_LOG_ERR, +- "connection_read_operation", "conn=%" NSPRIu64 " ber_peek_tag returns 0x%lx\n", conn->c_connid, *tag); ++ "connection_read_operation", "conn=%" PRIu64 " ber_peek_tag returns 0x%lx\n", conn->c_connid, *tag); + disconnect_server_nomutex( conn, conn->c_connid, -1, SLAPD_DISCONNECT_BER_PEEK, EPROTO ); + ret = CONN_DONE; + goto done; +@@ -1361,7 +1361,7 @@ void connection_make_readable(Connection *conn) + void connection_make_readable_nolock(Connection *conn) + { + conn->c_gettingber = 0; +- slapi_log_err(SLAPI_LOG_CONNS, "connection_make_readable_nolock", "making readable conn %" NSPRIu64 " fd=%d\n", ++ slapi_log_err(SLAPI_LOG_CONNS, "connection_make_readable_nolock", "making readable conn %" PRIu64 " fd=%d\n", + conn->c_connid, conn->c_sd); + if (!(conn->c_flags & CONN_FLAG_CLOSING)) { + /* if the connection is closing, try the close in connection_release_nolock */ +@@ -1388,7 +1388,7 @@ void connection_check_activity_level(Connection *conn) + /* update the last checked time */ + conn->c_private->previous_count_check_time = current_time(); + PR_ExitMonitor(conn->c_mutex); +- slapi_log_err(SLAPI_LOG_CONNS,"connection_check_activity_level", "conn %" NSPRIu64 " activity level = %d\n",conn->c_connid,delta_count); ++ slapi_log_err(SLAPI_LOG_CONNS,"connection_check_activity_level", "conn %" PRIu64 " activity level = %d\n",conn->c_connid,delta_count); + } + + typedef struct table_iterate_info_struct { +@@ -1450,7 +1450,7 @@ void connection_enter_leave_turbo(Connection *conn, int current_turbo_flag, int + double activet = 0.0; + connection_find_our_rank(conn,&connection_count, &our_rank); + slapi_log_err(SLAPI_LOG_CONNS,"connection_enter_leave_turbo", +- "conn %" NSPRIu64 " turbo rank = %d out of %d conns\n",conn->c_connid,our_rank,connection_count); ++ "conn %" PRIu64 " turbo rank = %d out of %d conns\n",conn->c_connid,our_rank,connection_count); + activet = (double)g_get_active_threadcnt(); + threshold_rank = (int)(activet * ((double)CONN_TURBO_PERCENTILE / 100.0)); + +@@ -1491,9 +1491,9 @@ void connection_enter_leave_turbo(Connection *conn, int current_turbo_flag, int + PR_ExitMonitor(conn->c_mutex); + if (current_mode != new_mode) { + if (current_mode) { +- slapi_log_err(SLAPI_LOG_CONNS,"connection_enter_leave_turbo", "conn %" NSPRIu64 " leaving turbo mode\n",conn->c_connid); ++ slapi_log_err(SLAPI_LOG_CONNS,"connection_enter_leave_turbo", "conn %" PRIu64 " leaving turbo mode\n",conn->c_connid); + } else { +- slapi_log_err(SLAPI_LOG_CONNS,"connection_enter_leave_turbo", "conn %" NSPRIu64 " entering turbo mode\n",conn->c_connid); ++ slapi_log_err(SLAPI_LOG_CONNS,"connection_enter_leave_turbo", "conn %" PRIu64 " entering turbo mode\n",conn->c_connid); + } + } + *new_turbo_flag = new_mode; +@@ -1617,12 +1617,12 @@ connection_threadmain() + ret = connection_read_operation(conn, op, &tag, &more_data); + if ((ret == CONN_DONE) || (ret == CONN_TIMEDOUT)) { + slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", +- "conn %" NSPRIu64 " read not ready due to %d - thread_turbo_flag %d more_data %d " ++ "conn %" PRIu64 " read not ready due to %d - thread_turbo_flag %d more_data %d " + "ops_initiated %d refcnt %d flags %d\n", conn->c_connid, ret, thread_turbo_flag, more_data, + conn->c_opsinitiated, conn->c_refcnt, conn->c_flags); + } else if (ret == CONN_FOUND_WORK_TO_DO) { + slapi_log_err(SLAPI_LOG_CONNS, "connection_threadmain", +- "conn %" NSPRIu64 " read operation successfully - thread_turbo_flag %d more_data %d " ++ "conn %" PRIu64 " read operation successfully - thread_turbo_flag %d more_data %d " + "ops_initiated %d refcnt %d flags %d\n", conn->c_connid, thread_turbo_flag, more_data, + conn->c_opsinitiated, conn->c_refcnt, conn->c_flags); + } +@@ -1648,7 +1648,7 @@ connection_threadmain() + if (thread_turbo_flag && !WORK_Q_EMPTY) { + thread_turbo_flag = 0; + slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", +- "conn %" NSPRIu64 " leaving turbo mode - pb_q is not empty %d\n", ++ "conn %" PRIu64 " leaving turbo mode - pb_q is not empty %d\n", + conn->c_connid,work_q_size); + } + #endif +@@ -1675,7 +1675,7 @@ connection_threadmain() + * connection_make_readable(conn); + */ + slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", +- "conn %" NSPRIu64 " leaving turbo mode due to %d\n", ++ "conn %" PRIu64 " leaving turbo mode due to %d\n", + conn->c_connid,ret); + goto done; + case CONN_SHUTDOWN: +@@ -1732,7 +1732,7 @@ connection_threadmain() + */ + conn->c_idlesince = curtime; + connection_activity(conn, maxthreads); +- slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", "conn %" NSPRIu64 " queued because more_data\n", ++ slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", "conn %" PRIu64 " queued because more_data\n", + conn->c_connid); + } else { + /* keep count of how many times maxthreads has blocked an operation */ +@@ -1814,7 +1814,7 @@ done: + /* If we're in turbo mode, we keep our reference to the connection alive */ + /* can't use the more_data var because connection could have changed in another thread */ + more_data = conn_buffered_data_avail_nolock(conn, &conn_closed) ? 1 : 0; +- slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", "conn %" NSPRIu64 " check more_data %d thread_turbo_flag %d\n", ++ slapi_log_err(SLAPI_LOG_CONNS,"connection_threadmain", "conn %" PRIu64 " check more_data %d thread_turbo_flag %d\n", + conn->c_connid,more_data,thread_turbo_flag); + if (!more_data) { + if (!thread_turbo_flag) { +@@ -1863,7 +1863,7 @@ connection_activity(Connection *conn, int maxthreads) + + if (connection_acquire_nolock (conn) == -1) { + slapi_log_err(SLAPI_LOG_CONNS, +- "connection_activity", "Could not acquire lock in connection_activity as conn %" NSPRIu64 " closing fd=%d\n", ++ "connection_activity", "Could not acquire lock in connection_activity as conn %" PRIu64 " closing fd=%d\n", + conn->c_connid,conn->c_sd); + /* XXX how to handle this error? */ + /* MAB: 25 Jan 01: let's return on error and pray this won't leak */ +@@ -2046,7 +2046,7 @@ connection_remove_operation( Connection *conn, Operation *op ) + + if ( *tmp == NULL ) + { +- slapi_log_err(SLAPI_LOG_ERR, "connection_remove_operation", "Can't find op %d for conn %" NSPRIu64 "\n", ++ slapi_log_err(SLAPI_LOG_ERR, "connection_remove_operation", "Can't find op %d for conn %" PRIu64 "\n", + (int)op->o_msgid, conn->c_connid); + } + else +@@ -2187,13 +2187,13 @@ log_ber_too_big_error(const Connection *conn, ber_len_t ber_len, + } + if (0 == ber_len) { + slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error", +- "conn=%" NSPRIu64 " fd=%d Incoming BER Element was too long, max allowable" ++ "conn=%" PRIu64 " fd=%d Incoming BER Element was too long, max allowable" + " is %" BERLEN_T " bytes. Change the nsslapd-maxbersize attribute in" + " cn=config to increase.\n", + conn->c_connid, conn->c_sd, maxbersize ); + } else { + slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error", +- "conn=%" NSPRIu64 " fd=%d Incoming BER Element was %" BERLEN_T " bytes, max allowable" ++ "conn=%" PRIu64 " fd=%d Incoming BER Element was %" BERLEN_T " bytes, max allowable" + " is %" BERLEN_T " bytes. Change the nsslapd-maxbersize attribute in" + " cn=config to increase.\n", + conn->c_connid, conn->c_sd, ber_len, maxbersize ); +@@ -2224,7 +2224,7 @@ disconnect_server_nomutex_ext( Connection *conn, PRUint64 opconnid, int opid, PR + if ( ( conn->c_sd != SLAPD_INVALID_SOCKET && + conn->c_connid == opconnid ) && !(conn->c_flags & CONN_FLAG_CLOSING) ) + { +- slapi_log_err(SLAPI_LOG_CONNS, "disconnect_server_nomutex_ext", "Setting conn %" NSPRIu64 " fd=%d " ++ slapi_log_err(SLAPI_LOG_CONNS, "disconnect_server_nomutex_ext", "Setting conn %" PRIu64 " fd=%d " + "to be disconnected: reason %d\n", conn->c_connid, conn->c_sd, reason); + /* + * PR_Close must be called before anything else is done because +@@ -2248,13 +2248,13 @@ disconnect_server_nomutex_ext( Connection *conn, PRUint64 opconnid, int opid, PR + */ + if (error && (EPIPE != error) ) { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d fd=%d closed error %d (%s) - %s\n", ++ "conn=%" PRIu64 " op=%d fd=%d closed error %d (%s) - %s\n", + conn->c_connid, opid, conn->c_sd, error, + slapd_system_strerror(error), + slapd_pr_strerror(reason)); + } else { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d fd=%d closed - %s\n", ++ "conn=%" PRIu64 " op=%d fd=%d closed - %s\n", + conn->c_connid, opid, conn->c_sd, + slapd_pr_strerror(reason)); + } +diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c +index bcafa4e..30da055 100644 +--- a/ldap/servers/slapd/conntable.c ++++ b/ldap/servers/slapd/conntable.c +@@ -395,7 +395,7 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e) + * 3 = The number of operations attempted that were blocked + * by max threads. + */ +- snprintf(maxthreadbuf, sizeof(maxthreadbuf), "%d:%"NSPRIu64":%"NSPRIu64"", ++ snprintf(maxthreadbuf, sizeof(maxthreadbuf), "%d:%"PRIu64":%"PRIu64"", + maxthreadstate, ct->c[i].c_maxthreadscount, + ct->c[i].c_maxthreadsblocked); + +@@ -431,17 +431,17 @@ connection_table_as_entry(Connection_Table *ct, Slapi_Entry *e) + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "currentconnections", vals ); + +- snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(num_conns)); ++ snprintf( buf, sizeof(buf), "%" PRIu64, slapi_counter_get_value(num_conns)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "totalconnections", vals ); + +- snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(conns_in_maxthreads)); ++ snprintf( buf, sizeof(buf), "%" PRIu64, slapi_counter_get_value(conns_in_maxthreads)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "currentconnectionsatmaxthreads", vals ); + +- snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(max_threads_count)); ++ snprintf( buf, sizeof(buf), "%" PRIu64, slapi_counter_get_value(max_threads_count)); + val.bv_val = buf; + val.bv_len = strlen( buf ); + attrlist_replace( &e->e_attrs, "maxthreadsperconnhits", vals ); +diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c +index 8f9e74e..52f2519 100644 +--- a/ldap/servers/slapd/control.c ++++ b/ldap/servers/slapd/control.c +@@ -335,7 +335,7 @@ get_ldapmessage_controls_ext( + slapi_pblock_set(pb, SLAPI_REQCONTROLS, NULL); + slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &ctrl_not_found); + slapi_pblock_set(pb, SLAPI_PWPOLICY, &ctrl_not_found); +- slapi_log_err(SLAPI_LOG_CONNS, "get_ldapmessage_controls_ext", "Warning: conn=%" NSPRIu64 " op=%d contains an empty list of controls\n", ++ slapi_log_err(SLAPI_LOG_CONNS, "get_ldapmessage_controls_ext", "Warning: conn=%" PRIu64 " op=%d contains an empty list of controls\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid); + } else { + /* len, ber_len_t is uint, not int, cannot be != -1, may be better to remove this check. */ +diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c +index a4ea4c0..5f2471e 100644 +--- a/ldap/servers/slapd/daemon.c ++++ b/ldap/servers/slapd/daemon.c +@@ -616,7 +616,7 @@ disk_monitoring_thread(void *nothing) + */ + if(disk_space < 4096){ /* 4 k */ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is critically low on disk (%s), " +- "remaining space: %" NSPRIu64 " Kb. Signaling slapd for shutdown...\n", dirstr , (disk_space / 1024)); ++ "remaining space: %" PRIu64 " Kb. Signaling slapd for shutdown...\n", dirstr , (disk_space / 1024)); + g_set_shutdown( SLAPI_SHUTDOWN_EXIT ); + return; + } +@@ -626,7 +626,7 @@ disk_monitoring_thread(void *nothing) + */ + if(verbose_logging != 0 && verbose_logging != LDAP_DEBUG_ANY){ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is low on disk (%s), remaining space: " +- "%" NSPRIu64 " Kb, temporarily setting error loglevel to the default level(%d).\n", dirstr, ++ "%" PRIu64 " Kb, temporarily setting error loglevel to the default level(%d).\n", dirstr, + (disk_space / 1024), SLAPD_DEFAULT_ERRORLOG_LEVEL); + /* Setting the log level back to zero, actually sets the value to LDAP_DEBUG_ANY */ + config_set_errorlog_level(CONFIG_LOGLEVEL_ATTRIBUTE, +@@ -640,7 +640,7 @@ disk_monitoring_thread(void *nothing) + */ + if(!logs_disabled && !logging_critical){ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is too low on disk (%s), remaining " +- "space: %" NSPRIu64 " Kb, disabling access and audit logging.\n", dirstr, (disk_space / 1024)); ++ "space: %" PRIu64 " Kb, disabling access and audit logging.\n", dirstr, (disk_space / 1024)); + config_set_accesslog_enabled(LOGGING_OFF); + config_set_auditlog_enabled(LOGGING_OFF); + config_set_auditfaillog_enabled(LOGGING_OFF); +@@ -653,7 +653,7 @@ disk_monitoring_thread(void *nothing) + */ + if(!deleted_rotated_logs && !logging_critical){ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is too low on disk (%s), remaining " +- "space: %" NSPRIu64 " Kb, deleting rotated logs.\n", dirstr, (disk_space / 1024)); ++ "space: %" PRIu64 " Kb, deleting rotated logs.\n", dirstr, (disk_space / 1024)); + log__delete_rotated_logs(); + deleted_rotated_logs = 1; + continue; +@@ -663,7 +663,7 @@ disk_monitoring_thread(void *nothing) + */ + if(disk_space < previous_mark){ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is too low on disk (%s), remaining " +- "space: %" NSPRIu64 " Kb\n", dirstr, (disk_space / 1024)); ++ "space: %" PRIu64 " Kb\n", dirstr, (disk_space / 1024)); + } + /* + * +@@ -674,7 +674,7 @@ disk_monitoring_thread(void *nothing) + * + */ + if(disk_space < halfway){ +- slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space on (%s) is too far below the threshold(%" NSPRIu64 " bytes). " ++ slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). " + "Waiting %d minutes for disk space to be cleaned up before shutting slapd down...\n", + dirstr, threshold, (grace_period / 60)); + time(&start); +@@ -697,7 +697,7 @@ disk_monitoring_thread(void *nothing) + * Excellent, we are back to acceptable levels, reset everything... + */ + slapi_log_err(SLAPI_LOG_INFO, "disk_monitoring_thread", "Available disk space is now " +- "acceptable (%" NSPRIu64 " bytes). Aborting shutdown, and restoring the log settings.\n", ++ "acceptable (%" PRIu64 " bytes). Aborting shutdown, and restoring the log settings.\n", + disk_space); + if(logs_disabled && using_accesslog){ + config_set_accesslog_enabled(LOGGING_ON); +@@ -721,7 +721,7 @@ disk_monitoring_thread(void *nothing) + * Disk space is critical, log an error, and shut it down now! + */ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is critically low " +- "on disk (%s), remaining space: %" NSPRIu64 " Kb. Signaling slapd for shutdown...\n", ++ "on disk (%s), remaining space: %" PRIu64 " Kb. Signaling slapd for shutdown...\n", + dirstr, (disk_space / 1024)); + g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL ); + return; +@@ -739,7 +739,7 @@ disk_monitoring_thread(void *nothing) + * If disk space was freed up we would of detected in the above while loop. So shut it down. + */ + slapi_log_err(SLAPI_LOG_ALERT, "disk_monitoring_thread", "Disk space is still too low " +- "(%" NSPRIu64 " Kb). Signaling slapd for shutdown...\n", (disk_space / 1024)); ++ "(%" PRIu64 " Kb). Signaling slapd for shutdown...\n", (disk_space / 1024)); + g_set_shutdown( SLAPI_SHUTDOWN_DISKFULL ); + + return; +@@ -1785,7 +1785,7 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll) + * trying to acquire a closing connection + */ + slapi_log_err(SLAPI_LOG_ERR, +- "handle_pr_read_ready", "connection_activity: abandoning conn %" NSPRIu64 " as " ++ "handle_pr_read_ready", "connection_activity: abandoning conn %" PRIu64 " as " + "fd=%d is already closing\n", c->c_connid,c->c_sd); + /* The call disconnect_server should do nothing, + * as the connection c should be already set to CLOSING */ +@@ -1843,7 +1843,7 @@ ns_handle_closure(struct ns_job_t *job) + #else + /* This doesn't actually confirm it's in the event loop thread, but it's a start */ + if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) { +- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_closure", "Attempt to close outside of event loop thread %" NSPRIu64 " for fd=%d\n", ++ slapi_log_err(SLAPI_LOG_ERR, "ns_handle_closure", "Attempt to close outside of event loop thread %" PRIu64 " for fd=%d\n", + c->c_connid, c->c_sd); + return; + } +@@ -1883,7 +1883,7 @@ ns_connection_post_io_or_closing(Connection *conn) + PR_ASSERT((conn->c_ns_close_jobs == 0) || (conn->c_ns_close_jobs == 1)); + if (conn->c_ns_close_jobs) { + slapi_log_err(SLAPI_LOG_CONNS, "ns_connection_post_io_or_closing", "Already a close " +- "job in progress on conn %" NSPRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd); ++ "job in progress on conn %" PRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd); + return; + } else { + /* just make sure we schedule the event to be closed in a timely manner */ +@@ -1898,10 +1898,10 @@ ns_connection_post_io_or_closing(Connection *conn) + #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); ++ "for conn %" PRIu64 " 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); ++ "for conn %" PRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd); + } + + } +@@ -1938,10 +1938,10 @@ ns_connection_post_io_or_closing(Connection *conn) + #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); ++ "conn %" PRIu64 " 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); ++ "conn %" PRIu64 " for fd=%d\n", conn->c_connid, conn->c_sd); + } + } + #endif +@@ -1964,14 +1964,14 @@ ns_handle_pr_read_ready(struct ns_job_t *job) + #else + /* This doesn't actually confirm it's in the event loop thread, but it's a start */ + if (NS_JOB_IS_THREAD(ns_job_get_type(job)) != 0) { +- slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "Attempt to handle read ready outside of event loop thread %" NSPRIu64 " for fd=%d\n", ++ slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "Attempt to handle read ready outside of event loop thread %" PRIu64 " for fd=%d\n", + c->c_connid, c->c_sd); + return; + } + #endif + + PR_EnterMonitor(c->c_mutex); +- slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "activity on conn %" NSPRIu64 " for fd=%d\n", ++ slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "activity on conn %" PRIu64 " for fd=%d\n", + c->c_connid, c->c_sd); + /* if we were called due to some i/o event, see what the state of the socket is */ + if (slapi_is_loglevel_set(SLAPI_LOG_CONNS) && !NS_JOB_IS_TIMER(ns_job_get_output_type(job)) && c && c->c_sd) { +@@ -1980,16 +1980,16 @@ ns_handle_pr_read_ready(struct ns_job_t *job) + ssize_t rc = recv(c->c_sd, buf, sizeof(buf), MSG_PEEK); + if (!rc) { + slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "socket is closed conn" +- " %" NSPRIu64 " for fd=%d\n", c->c_connid, c->c_sd); ++ " %" PRIu64 " for fd=%d\n", c->c_connid, c->c_sd); + } else if (rc > 0) { + slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "socket read data available" +- " for conn %" NSPRIu64 " for fd=%d\n", c->c_connid, c->c_sd); ++ " for conn %" PRIu64 " for fd=%d\n", c->c_connid, c->c_sd); + } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "socket has no data available" +- " conn %" NSPRIu64 " for fd=%d\n", c->c_connid, c->c_sd); ++ " conn %" PRIu64 " for fd=%d\n", c->c_connid, c->c_sd); + } else { + slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "socket has error [%d] " +- "conn %" NSPRIu64 " for fd=%d\n", errno, c->c_connid, c->c_sd); ++ "conn %" PRIu64 " for fd=%d\n", errno, c->c_connid, c->c_sd); + } + } + connection_release_nolock_ext(c, 1); /* release ref acquired when job was added */ +@@ -2013,7 +2013,7 @@ ns_handle_pr_read_ready(struct ns_job_t *job) + * trying to acquire a closing connection + */ + slapi_log_err(SLAPI_LOG_ERR, "ns_handle_pr_read_ready", "connection_activity: abandoning" +- " conn %" NSPRIu64 " as fd=%d is already closing\n", c->c_connid, c->c_sd); ++ " conn %" PRIu64 " as fd=%d is already closing\n", c->c_connid, c->c_sd); + /* The call disconnect_server should do nothing, + * as the connection c should be already set to CLOSING */ + disconnect_server_nomutex_ext(c, c->c_connid, -1, +@@ -2021,7 +2021,7 @@ ns_handle_pr_read_ready(struct ns_job_t *job) + 0 /* do not schedule closure, do it next */); + ns_handle_closure_nomutex(c); + } else { +- slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "queued conn %" NSPRIu64 " for fd=%d\n", ++ slapi_log_err(SLAPI_LOG_CONNS, "ns_handle_pr_read_ready", "queued conn %" PRIu64 " for fd=%d\n", + c->c_connid, c->c_sd); + } + PR_ExitMonitor(c->c_mutex); +diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c +index a16718a..e4e82a3 100644 +--- a/ldap/servers/slapd/delete.c ++++ b/ldap/servers/slapd/delete.c +@@ -260,7 +260,7 @@ static void op_shared_delete (Slapi_PBlock *pb) + + if (!internal_op ) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d DEL dn=\"%s\"%s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d DEL dn=\"%s\"%s\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + slapi_sdn_get_dn(sdn), +diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c +index abacc57..b56e3da 100644 +--- a/ldap/servers/slapd/entry.c ++++ b/ldap/servers/slapd/entry.c +@@ -3095,7 +3095,7 @@ slapi_entry_attr_set_ulong( Slapi_Entry* e, const char *type, uint64_t l) + struct berval *bvals[2]; + bvals[0] = &bv; + bvals[1] = NULL; +- sprintf(value,"%" NSPRIu64, l); ++ sprintf(value,"%" PRIu64, l); + bv.bv_val = value; + bv.bv_len = strlen( value ); + slapi_entry_attr_replace( e, type, bvals ); +diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c +index 7e41b8c..6a5d2e3 100644 +--- a/ldap/servers/slapd/extendop.c ++++ b/ldap/servers/slapd/extendop.c +@@ -247,14 +247,14 @@ do_extended( Slapi_PBlock *pb ) + if ( NULL == ( name = extended_op_oid2string( extoid ))) { + slapi_log_err(SLAPI_LOG_ARGS, "do_extended", "oid (%s)\n", extoid); + +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d EXT oid=\"%s\"\n", ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d EXT oid=\"%s\"\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, extoid ); + } else { + slapi_log_err(SLAPI_LOG_ARGS, "do_extended", "oid (%s-%s)\n", + extoid, name); + + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d EXT oid=\"%s\" name=\"%s\"\n", ++ "conn=%" PRIu64 " op=%d EXT oid=\"%s\" name=\"%s\"\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, extoid, name ); + } + +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index afedd5b..a63c6a6 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -2769,7 +2769,7 @@ log__open_accesslogfile(int logfile_state, int locked) + while ( logp) { + log_convert_time (logp->l_ctime, tbuf, 1 /*short*/); + PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%" +- NSPRI64 "d)\n", PREVLOGFILE, loginfo.log_access_file, tbuf, ++ PRId64 "d)\n", PREVLOGFILE, loginfo.log_access_file, tbuf, + logp->l_ctime, logp->l_size); + LOG_WRITE(fpinfo, buffer, strlen(buffer), 0); + logp = logp->l_next; +@@ -2907,7 +2907,7 @@ log_rotate: + if (type == LOG_SIZE_EXCEEDED) { + slapi_log_err(SLAPI_LOG_TRACE, "log__needrotation", + "LOGINFO:End of Log because size exceeded(Max:%" +- NSPRI64 "d bytes) (Is:%" NSPRI64 "d bytes)\n", ++ PRId64 "d bytes) (Is:%" PRId64 "d bytes)\n", + maxlogsize, f_size); + } else if ( type == LOG_EXPIRED) { + slapi_log_err(SLAPI_LOG_TRACE, "log__needrotation", +@@ -4636,7 +4636,7 @@ log__open_errorlogfile(int logfile_state, int locked) + while (logp) { + log_convert_time (logp->l_ctime, tbuf, 1 /*short */); + PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%" +- NSPRI64 "d)\n", PREVLOGFILE, loginfo.log_error_file, tbuf, ++ PRId64 "d)\n", PREVLOGFILE, loginfo.log_error_file, tbuf, + logp->l_ctime, logp->l_size); + LOG_WRITE(fpinfo, buffer, strlen(buffer), 0); + logp = logp->l_next; +@@ -4763,7 +4763,7 @@ log__open_auditlogfile(int logfile_state, int locked) + while ( logp) { + log_convert_time (logp->l_ctime, tbuf, 1 /*short */); + PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%" +- NSPRI64 "d)\n", PREVLOGFILE, loginfo.log_audit_file, tbuf, ++ PRId64 "d)\n", PREVLOGFILE, loginfo.log_audit_file, tbuf, + logp->l_ctime, logp->l_size); + LOG_WRITE(fpinfo, buffer, strlen(buffer), 0); + logp = logp->l_next; +@@ -4889,7 +4889,7 @@ log__open_auditfaillogfile(int logfile_state, int locked) + while ( logp) { + log_convert_time (logp->l_ctime, tbuf, 1 /*short */); + PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%" +- NSPRI64 "d)\n", PREVLOGFILE, loginfo.log_auditfail_file, tbuf, ++ PRId64 "d)\n", PREVLOGFILE, loginfo.log_auditfail_file, tbuf, + logp->l_ctime, logp->l_size); + LOG_WRITE(fpinfo, buffer, strlen(buffer), 0); + logp = logp->l_next; +diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c +index e23fe67..da66b44 100644 +--- a/ldap/servers/slapd/modify.c ++++ b/ldap/servers/slapd/modify.c +@@ -680,7 +680,7 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw) + + if ( !internal_op ) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"%s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + slapi_sdn_get_dn(sdn), +@@ -1227,7 +1227,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old + { + if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, + slapi_sdn_get_dn(&sdn)); + } +@@ -1267,7 +1267,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old + if (proxydn){ + proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); + } +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"%s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, + slapi_sdn_get_dn(&sdn), proxystr ? proxystr : ""); + } +@@ -1312,7 +1312,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old + proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); + } + +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, + slapi_sdn_get_dn(&sdn), + proxystr ? proxystr : "", +@@ -1338,7 +1338,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old + + if ( !internal_op ) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + slapi_sdn_get_dn(&sdn), +@@ -1381,7 +1381,7 @@ static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old + + if ( !internal_op ) + { +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + slapi_sdn_get_dn(&sdn), +diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c +index 15f5210..69cca40 100644 +--- a/ldap/servers/slapd/modrdn.c ++++ b/ldap/servers/slapd/modrdn.c +@@ -463,7 +463,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args) + if ( !internal_op ) + { + slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", ++ "conn=%" PRIu64 " op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + dn, +@@ -497,7 +497,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args) + { + if ( !internal_op ) { + slapi_log_err(SLAPI_LOG_ARGS, "op_shared_rename", +- "conn=%" NSPRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n", ++ "conn=%" PRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + (NULL == newrdn) ? "(null)" : newrdn); +@@ -531,7 +531,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args) + "Syntax check of newSuperior failed\n"); + if (!internal_op) { + slapi_log_err(SLAPI_LOG_ARGS, "op_shared_rename", +- "conn=%" NSPRIu64 " op=%d MODRDN invalid new superior (\"%s\")", ++ "conn=%" PRIu64 " op=%d MODRDN invalid new superior (\"%s\")", + pb->pb_conn->c_connid, + pb->pb_op->o_opid, + newsuperior ? newsuperior : "(null)"); +diff --git a/ldap/servers/slapd/monitor.c b/ldap/servers/slapd/monitor.c +index f1fb38f..8d1788f 100644 +--- a/ldap/servers/slapd/monitor.c ++++ b/ldap/servers/slapd/monitor.c +@@ -60,19 +60,19 @@ monitor_info(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *ret + + connection_table_as_entry(the_connection_table, e); + +- val.bv_len = snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_initiated) ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%" PRIu64, slapi_counter_get_value(ops_initiated) ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "opsinitiated", vals ); + +- val.bv_len = snprintf( buf, sizeof(buf), "%" NSPRIu64, slapi_counter_get_value(ops_completed) ); ++ val.bv_len = snprintf( buf, sizeof(buf), "%" PRIu64, slapi_counter_get_value(ops_completed) ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "opscompleted", vals ); + +- val.bv_len = snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_entries_sent() ); ++ val.bv_len = snprintf ( buf, sizeof(buf), "%" PRIu64, g_get_num_entries_sent() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "entriessent", vals ); + +- val.bv_len = snprintf ( buf, sizeof(buf), "%" NSPRIu64, g_get_num_bytes_sent() ); ++ val.bv_len = snprintf ( buf, sizeof(buf), "%" PRIu64, g_get_num_bytes_sent() ); + val.bv_val = buf; + attrlist_replace( &e->e_attrs, "bytessent", vals ); + +diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c +index ccbc549..00fb9b8 100644 +--- a/ldap/servers/slapd/operation.c ++++ b/ldap/servers/slapd/operation.c +@@ -580,7 +580,7 @@ int slapi_connection_acquire(Slapi_Connection *conn) + { + /* This may happen while other threads are still working on this connection */ + slapi_log_err(SLAPI_LOG_ERR, "slapi_connection_acquire", +- "conn=%" NSPRIu64 " fd=%d Attempt to acquire connection in the closing state\n", ++ "conn=%" PRIu64 " fd=%d Attempt to acquire connection in the closing state\n", + conn->c_connid, conn->c_sd); + rc = -1; + } +@@ -606,7 +606,7 @@ slapi_connection_remove_operation( Slapi_PBlock *pb, Slapi_Connection *conn, Sla + if ( *tmp == NULL ) { + if (op) { + slapi_log_err(SLAPI_LOG_ERR, "slapi_connection_remove_operation", +- "Can't find op %d for conn %" NSPRIu64 "\n", ++ "Can't find op %d for conn %" PRIu64 "\n", + (int)op->o_msgid, conn->c_connid); + } else { + slapi_log_err(SLAPI_LOG_ERR, "slapi_connection_remove_operation", +@@ -620,7 +620,7 @@ slapi_connection_remove_operation( Slapi_PBlock *pb, Slapi_Connection *conn, Sla + /* connection_release_nolock(conn); */ + if (conn->c_refcnt <= 0) { + slapi_log_err(SLAPI_LOG_ERR, "slapi_connection_remove_operation", +- "conn=%" NSPRIu64 " fd=%d Attempt to release connection that is not acquired\n", ++ "conn=%" PRIu64 " fd=%d Attempt to release connection that is not acquired\n", + conn->c_connid, conn->c_sd); + rc = -1; + } else { +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index 3ce7970..4682a73 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -289,7 +289,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result) + { + char *fmtstr; + +-#define SLAPD_SEARCH_FMTSTR_BASE "conn=%" NSPRIu64 " op=%d SRCH base=\"%s\" scope=%d " ++#define SLAPD_SEARCH_FMTSTR_BASE "conn=%" PRIu64 " op=%d SRCH base=\"%s\" scope=%d " + #define SLAPD_SEARCH_FMTSTR_BASE_INT "conn=%s op=%d SRCH base=\"%s\" scope=%d " + #define SLAPD_SEARCH_FMTSTR_REMAINDER " attrs=%s%s%s\n" + +@@ -1744,7 +1744,7 @@ void op_shared_log_error_access (Slapi_PBlock *pb, const char *type, const char + proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); + } + +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d %s dn=\"%s\"%s, %s\n", ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d %s dn=\"%s\"%s, %s\n", + ( pb->pb_conn ? pb->pb_conn->c_connid : 0), + ( pb->pb_op ? pb->pb_op->o_opid : 0), + type, +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index a30e2fa..e8c80e7 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -310,7 +310,7 @@ pagedresults_free_one( Connection *conn, Operation *op, int index ) + PR_EnterMonitor(conn->c_mutex); + if (conn->c_pagedresults.prl_count <= 0) { + slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", +- "conn=%" NSPRIu64 " paged requests list count is %d\n", ++ "conn=%" PRIu64 " paged requests list count is %d\n", + conn->c_connid, conn->c_pagedresults.prl_count); + } else if (index < conn->c_pagedresults.prl_maxlen) { + PagedResults *prp = conn->c_pagedresults.prl_list + index; +diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c +index 793bea3..2d0badc 100644 +--- a/ldap/servers/slapd/psearch.c ++++ b/ldap/servers/slapd/psearch.c +@@ -283,7 +283,7 @@ ps_send_results( void *arg ) + + if (conn_acq_flag) { + slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", +- "conn=%" NSPRIu64 " op=%d Could not acquire the connection - psearch aborted\n", ++ "conn=%" PRIu64 " op=%d Could not acquire the connection - psearch aborted\n", + ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid); + } + +@@ -293,7 +293,7 @@ ps_send_results( void *arg ) + /* Check for an abandoned operation */ + if ( ps->ps_pblock->pb_op == NULL || slapi_op_abandoned( ps->ps_pblock ) ) { + slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", +- "conn=%" NSPRIu64 " op=%d The operation has been abandoned\n", ++ "conn=%" PRIu64 " op=%d The operation has been abandoned\n", + ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid); + break; + } +@@ -351,7 +351,7 @@ ps_send_results( void *arg ) + ectrls, attrs, attrsonly ); + if (rc) { + slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", +- "conn=%" NSPRIu64 " op=%d Error %d sending entry %s with op status %d\n", ++ "conn=%" PRIu64 " op=%d Error %d sending entry %s with op status %d\n", + ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid, + rc, slapi_entry_get_dn_const(ec), ps->ps_pblock->pb_op->o_status); + } +@@ -400,7 +400,7 @@ ps_send_results( void *arg ) + PR_EnterMonitor(conn->c_mutex); + + slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", +- "conn=%" NSPRIu64 " op=%d Releasing the connection and operation\n", ++ "conn=%" PRIu64 " op=%d Releasing the connection and operation\n", + conn->c_connid, ps->ps_pblock->pb_op->o_opid); + /* Delete this op from the connection's list */ + connection_remove_operation_ext( ps->ps_pblock, conn, ps->ps_pblock->pb_op ); +@@ -535,7 +535,7 @@ ps_service_persistent_searches( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t ch + } + + slapi_log_err(SLAPI_LOG_CONNS, "ps_service_persistent_searches", +- "conn=%" NSPRIu64 " op=%d entry %s with chgtype %d " ++ "conn=%" PRIu64 " op=%d entry %s with chgtype %d " + "matches the ps changetype %d\n", + ps->ps_pblock->pb_conn->c_connid, + ps->ps_pblock->pb_op->o_opid, +diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c +index 5c38bae..56257c3 100644 +--- a/ldap/servers/slapd/result.c ++++ b/ldap/servers/slapd/result.c +@@ -1980,7 +1980,7 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie + if ( !internal_op ) + { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d RESULT err=%d" ++ "conn=%" PRIu64 " op=%d RESULT err=%d" + " tag=%" BERTAG_T " nentries=%d etime=%s%s%s" + ", SASL bind in progress\n", + op->o_connid, +@@ -2012,7 +2012,7 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie + if ( !internal_op ) + { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d RESULT err=%d" ++ "conn=%" PRIu64 " op=%d RESULT err=%d" + " tag=%" BERTAG_T " nentries=%d etime=%s%s%s" + " dn=\"%s\"\n", + op->o_connid, +@@ -2040,7 +2040,7 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie + if ( !internal_op ) + { + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d RESULT err=%d" ++ "conn=%" PRIu64 " op=%d RESULT err=%d" + " tag=%" BERTAG_T " nentries=%d etime=%s%s%s" + " pr_idx=%d pr_cookie=%d\n", + op->o_connid, +@@ -2073,7 +2073,7 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie + ext_str = ""; + } + slapi_log_access( LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d RESULT err=%d" ++ "conn=%" PRIu64 " op=%d RESULT err=%d" + " tag=%" BERTAG_T " nentries=%d etime=%s%s%s%s\n", + op->o_connid, + op->o_opid, +@@ -2142,7 +2142,7 @@ log_entry( Operation *op, Slapi_Entry *e ) + + if ( !internal_op ) + { +- slapi_log_access( LDAP_DEBUG_STATS2, "conn=%" NSPRIu64 " op=%d ENTRY dn=\"%s\"\n", ++ slapi_log_access( LDAP_DEBUG_STATS2, "conn=%" PRIu64 " op=%d ENTRY dn=\"%s\"\n", + op->o_connid, op->o_opid, + slapi_entry_get_dn_const(e)); + } +@@ -2167,7 +2167,7 @@ log_referral( Operation *op ) + + if ( !internal_op ) + { +- slapi_log_access( LDAP_DEBUG_STATS2, "conn=%" NSPRIu64 " op=%d REFERRAL\n", ++ slapi_log_access( LDAP_DEBUG_STATS2, "conn=%" PRIu64 " op=%d REFERRAL\n", + op->o_connid, op->o_opid ); + } + else +diff --git a/ldap/servers/slapd/sasl_io.c b/ldap/servers/slapd/sasl_io.c +index 1337e1c..9458083 100644 +--- a/ldap/servers/slapd/sasl_io.c ++++ b/ldap/servers/slapd/sasl_io.c +@@ -198,17 +198,17 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + /* first we need the length bytes */ + ret = PR_Recv(fd->lower, buffer, amount, flags, timeout); + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", +- "Read sasl packet length returned %d on connection %" NSPRIu64 "\n", ++ "Read sasl packet length returned %d on connection %" PRIu64 "\n", + ret, c->c_connid); + if (ret <= 0) { + *err = PR_GetError(); + if (ret == 0) { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", +- "Connection closed while reading sasl packet length on connection %" NSPRIu64 "\n", ++ "Connection closed while reading sasl packet length on connection %" PRIu64 "\n", + c->c_connid ); + } else { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", +- "Error reading sasl packet length on connection %" NSPRIu64 " %d:%s\n", ++ "Error reading sasl packet length on connection %" PRIu64 " %d:%s\n", + c->c_connid, *err, slapd_pr_strerror(*err) ); + } + return ret; +@@ -226,7 +226,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + if (sp->encrypted_buffer_offset < sizeof(buffer)) { + slapi_log_err(SLAPI_LOG_CONNS, + "sasl_io_start_packet", "Read only %d bytes of sasl packet " +- "length on connection %" NSPRIu64 "\n", ret, c->c_connid ); ++ "length on connection %" PRIu64 "\n", ret, c->c_connid ); + #if defined(EWOULDBLOCK) + errno = EWOULDBLOCK; + #elif defined(EAGAIN) +@@ -251,7 +251,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + ber_len_t ber_len = 0; + ber_tag_t tag = 0; + +- slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d " ++ slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" PRIu64 " fd=%d " + "Sent an LDAP message that was not encrypted.\n", c->c_connid, + c->c_sd); + +@@ -265,7 +265,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + /* Is the ldap operation too large? */ + if(ber_len > maxbersize){ + slapi_log_err(SLAPI_LOG_ERR, "sasl_io_start_packet", +- "conn=%" NSPRIu64 " fd=%d Incoming BER Element was too long, max allowable " ++ "conn=%" PRIu64 " fd=%d Incoming BER Element was too long, max allowable " + "is %" BERLEN_T " bytes. Change the nsslapd-maxbersize attribute in " + "cn=config to increase.\n", + c->c_connid, c->c_sd, maxbersize ); +@@ -305,7 +305,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + } else if (ret > 0) { + slapi_log_err(SLAPI_LOG_CONNS, + "sasl_io_start_packet", +- "Continued: read sasl packet length returned %d on connection %" NSPRIu64 "\n", ++ "Continued: read sasl packet length returned %d on connection %" PRIu64 "\n", + ret, c->c_connid); + if((ret + sp->encrypted_buffer_offset) > sp->encrypted_buffer_size){ + sasl_io_resize_encrypted_buffer(sp, ret + sp->encrypted_buffer_offset); +@@ -316,7 +316,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + *err = PR_GetError(); + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", + "Error reading sasl packet length on connection " +- "%" NSPRIu64 " %d:%s\n", c->c_connid, *err, slapd_pr_strerror(*err) ); ++ "%" PRIu64 " %d:%s\n", c->c_connid, *err, slapd_pr_strerror(*err) ); + return ret; + } + } +@@ -360,7 +360,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + tag = *ber->ber_ptr++; + if (*ber->ber_ptr == LDAP_REQ_UNBIND){ + #endif +- slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d " ++ slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" PRIu64 " fd=%d " + "Received unencrypted UNBIND operation.\n", c->c_connid, + c->c_sd); + sp->encrypted_buffer_count = sp->encrypted_buffer_offset; +@@ -368,7 +368,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + ber_free(ber, 1); + return SASL_IO_BUFFER_NOT_ENCRYPTED; + } +- slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d " ++ slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" PRIu64 " fd=%d " + "Error: received an LDAP message (tag 0x%lx) that was not encrypted.\n", + #ifdef USE_OPENLDAP + c->c_connid, c->c_sd, (long unsigned int)tag); +@@ -380,7 +380,7 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt + + done: + /* If we got here we have garbage, or a denied LDAP operation */ +- slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" NSPRIu64 " fd=%d " ++ slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", "conn=%" PRIu64 " fd=%d " + "Error: received an invalid message that was not encrypted.\n", + c->c_connid, c->c_sd); + +@@ -399,7 +399,7 @@ done: + packet_length += sizeof(uint32_t); + + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_start_packet", +- "read sasl packet length %ld on connection %" NSPRIu64 "\n", ++ "read sasl packet length %ld on connection %" PRIu64 "\n", + packet_length, c->c_connid ); + + /* Check if the packet length is larger than our max allowed. A +@@ -432,17 +432,17 @@ sasl_io_read_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime timeout, PRInt3 + size_t bytes_remaining_to_read = sp->encrypted_buffer_count - sp->encrypted_buffer_offset; + + slapi_log_err(SLAPI_LOG_CONNS, +- "sasl_io_read_packet", "Reading %lu bytes for connection %" NSPRIu64 "\n", ++ "sasl_io_read_packet", "Reading %lu bytes for connection %" PRIu64 "\n", + bytes_remaining_to_read, c->c_connid ); + ret = PR_Recv(fd->lower, sp->encrypted_buffer + sp->encrypted_buffer_offset, bytes_remaining_to_read, flags, timeout); + if (ret <= 0) { + *err = PR_GetError(); + if (ret == 0) { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_read_packet", +- "Connection closed while reading sasl packet on connection %" NSPRIu64 "\n", c->c_connid ); ++ "Connection closed while reading sasl packet on connection %" PRIu64 "\n", c->c_connid ); + } else { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_read_packet", +- "Error reading sasl packet on connection %" NSPRIu64 " %d:%s\n", ++ "Error reading sasl packet on connection %" PRIu64 " %d:%s\n", + c->c_connid, *err, slapd_pr_strerror(*err) ); + } + return ret; +@@ -464,10 +464,10 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + /* Do we have decrypted data buffered from 'before' ? */ + bytes_in_buffer = sp->decrypted_buffer_count - sp->decrypted_buffer_offset; + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Connection %" NSPRIu64 " len %d bytes_in_buffer %lu\n", ++ "Connection %" PRIu64 " len %d bytes_in_buffer %lu\n", + c->c_connid, len, bytes_in_buffer ); + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Connection %" NSPRIu64 " len %d encrypted buffer count %lu\n", ++ "Connection %" PRIu64 " len %d encrypted buffer count %lu\n", + c->c_connid, len, sp->encrypted_buffer_count ); + if (0 == bytes_in_buffer) { + /* If there wasn't buffered decrypted data, we need to get some... */ +@@ -502,7 +502,7 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + */ + if (!sasl_io_finished_packet(sp)) { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Connection %" NSPRIu64 " - not finished reading packet yet\n", c->c_connid); ++ "Connection %" PRIu64 " - not finished reading packet yet\n", c->c_connid); + #if defined(EWOULDBLOCK) + errno = EWOULDBLOCK; + #elif defined(EAGAIN) +@@ -516,7 +516,7 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + const char *output_buffer = NULL; + unsigned int output_length = 0; + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Finished reading packet for connection %" NSPRIu64 "\n", c->c_connid ); ++ "Finished reading packet for connection %" PRIu64 "\n", c->c_connid ); + /* Now decode it */ + ret = sasl_decode(c->c_sasl_conn,sp->encrypted_buffer,sp->encrypted_buffer_count,&output_buffer,&output_length); + /* even if decode fails, need re-initialize the encrypted_buffer */ +@@ -524,7 +524,7 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + sp->encrypted_buffer_count = 0; + if (SASL_OK == ret) { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Decoded packet length %u for connection %" NSPRIu64 "\n", output_length, c->c_connid ); ++ "Decoded packet length %u for connection %" PRIu64 "\n", output_length, c->c_connid ); + if (output_length) { + sasl_io_resize_decrypted_buffer(sp,output_length); + memcpy(sp->decrypted_buffer,output_buffer,output_length); +@@ -534,7 +534,7 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + } + } else { + slapi_log_err(SLAPI_LOG_ERR, "sasl_io_recv", +- "Failed to decode packet for connection %" NSPRIu64 "\n", c->c_connid ); ++ "Failed to decode packet for connection %" PRIu64 "\n", c->c_connid ); + PR_SetError(PR_IO_ERROR, 0); + return PR_FAILURE; + } +@@ -552,11 +552,11 @@ sasl_io_recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, + sp->decrypted_buffer_offset = 0; + sp->decrypted_buffer_count = 0; + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "All decrypted data returned for connection %" NSPRIu64 "\n", c->c_connid ); ++ "All decrypted data returned for connection %" PRIu64 "\n", c->c_connid ); + } else { + sp->decrypted_buffer_offset += bytes_to_return; + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_recv", +- "Returning %lu bytes to caller %lu bytes left to return for connection %" NSPRIu64 "\n", ++ "Returning %lu bytes to caller %lu bytes left to return for connection %" PRIu64 "\n", + bytes_to_return, sp->decrypted_buffer_count - sp->decrypted_buffer_offset, c->c_connid ); + } + ret = bytes_to_return; +@@ -772,11 +772,11 @@ sasl_io_enable(Connection *c, void *data /* UNUSED */) + rv = PR_PushIOLayer(c->c_prfd, PR_TOP_IO_LAYER, layer); + if (rv) { + slapi_log_err(SLAPI_LOG_ERR, "sasl_io_enable", +- "Error enabling sasl io on connection %" NSPRIu64 " %d:%s\n", ++ "Error enabling sasl io on connection %" PRIu64 " %d:%s\n", + c->c_connid, rv, slapd_pr_strerror(rv) ); + } else { + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_enable", +- "Enabled sasl io on connection %" NSPRIu64 " \n", c->c_connid); ++ "Enabled sasl io on connection %" PRIu64 " \n", c->c_connid); + debug_print_layers(c->c_prfd); + } + } +@@ -794,7 +794,7 @@ sasl_io_cleanup(Connection *c, void *data /* UNUSED */) + int ret = 0; + + slapi_log_err(SLAPI_LOG_CONNS, "sasl_io_cleanup", +- "Connection %" NSPRIu64 "\n", c->c_connid); ++ "Connection %" PRIu64 "\n", c->c_connid); + + ret = sasl_pop_IO_layer(c->c_prfd, 0 /* do not close */); + +diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c +index 9e5d1f0..2d6fb64 100644 +--- a/ldap/servers/slapd/saslbind.c ++++ b/ldap/servers/slapd/saslbind.c +@@ -929,7 +929,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb) + Slapi_Operation *operation; + slapi_pblock_get( pb, SLAPI_OPERATION, &operation); + slapi_log_err(SLAPI_LOG_CONNS, "ids_sasl_check_bind", +- "cleaning up sasl IO conn=%" NSPRIu64 " op=%d complete=%d continuing=%d\n", ++ "cleaning up sasl IO conn=%" PRIu64 " op=%d complete=%d continuing=%d\n", + pb->pb_conn->c_connid, operation->o_opid, + (pb->pb_conn->c_flags & CONN_FLAG_SASL_COMPLETE), continuing); + /* reset flag */ +diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c +index 670347e..ea8b479 100644 +--- a/ldap/servers/slapd/search.c ++++ b/ldap/servers/slapd/search.c +@@ -380,7 +380,7 @@ free_and_return:; + static void log_search_access (Slapi_PBlock *pb, const char *base, int scope, const char *fstr, const char *msg) + { + slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" NSPRIu64 " op=%d SRCH base=\"%s\" scope=%d filter=\"%s\", %s\n", ++ "conn=%" PRIu64 " op=%d SRCH base=\"%s\" scope=%d filter=\"%s\", %s\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid, + base, scope, fstr, msg ? msg : ""); + +diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h +index 5871bf0..abfad20 100644 +--- a/ldap/servers/slapd/slap.h ++++ b/ldap/servers/slapd/slap.h +@@ -72,13 +72,8 @@ static char ptokPBE[34] = "Internal (Software) Token "; + #include + #include + +-/* Required to get portable printf/scanf format macros */ +-#ifdef HAVE_INTTYPES_H +-#include +- +-#else +-#error Need to define portable format macros such as PRIu64 +-#endif /* HAVE_INTTYPES_H */ ++/* Provides our int types and platform specific requirements. */ ++#include + + #define LOG_INTERNAL_OP_CON_ID "Internal" + #define LOG_INTERNAL_OP_OP_ID -1 +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 725fa1c..ec8917d 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -27,6 +27,9 @@ + extern "C" { + #endif + ++/* Provides our int types and platform specific requirements. */ ++#include ++ + #include "prtypes.h" + #include "ldap.h" + #include "prprf.h" +@@ -57,17 +60,6 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...) + ; + #endif + +-/* NSPR uses the print macros a bit differently than ANSI C. We +- * need to use ll for a 64-bit integer, even when a long is 64-bit. +- */ +-#if defined(HAVE_LONG_LONG) && PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) +-#define NSPRIu64 "lu" +-#define NSPRI64 "l" +-#else /* just assume long long is used */ +-#define NSPRIu64 "llu" +-#define NSPRI64 "ll" +-#endif +- + /* OpenLDAP uses unsigned long for ber_tag_t and ber_len_t but mozldap uses unsigned int */ + /* use this macro for printf statements for ber_tag_t and ber_len_t */ + #if defined(USE_OPENLDAP) +diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h +index dd180a7..0c76580 100644 +--- a/ldap/servers/slapd/slapi-private.h ++++ b/ldap/servers/slapd/slapi-private.h +@@ -30,6 +30,9 @@ extern "C" { + */ + #include "slapi-plugin-compat4.h" + ++/* slapi platform abstraction functions. */ ++#include ++ + /* Define our internal logging macro */ + #define slapi_log_err(level, subsystem, fmt, ...) + #ifdef LDAP_ERROR_LOGGING +@@ -1363,26 +1366,33 @@ long long slapi_parse_duration_longlong(const char *value); + int slapi_is_duration_valid(const char *value); + + /** +- * Populate the pointers with the system memory information. +- * At this time, Linux is the only "reliable" system for returning these values +- * +- * \param pagesize Will return the system page size in bytes. +- * \param pages The total number of memory pages on the system. May include swap pages depending on OS. +- * \param procpages Number of memory pages our current process is consuming. May not be accurate on all platforms as this could be the VMSize rather than the actual number of consumed pages. +- * \param availpages Number of available pages of memory on the system. Not all operating systems set this correctly. +- * +- * \return 0 on success, non-zero on failure to determine memory sizings. ++ * Possible results of a cachesize check + */ +-int util_info_sys_pages(size_t *pagesize, size_t *pages, size_t *procpages, size_t *availpages); +- ++typedef enum _util_cachesize_result { ++ /** ++ * The requested cachesize was valid and can be used. ++ */ ++ UTIL_CACHESIZE_VALID = 0, ++ /** ++ * The requested cachesize may cause OOM and was reduced. ++ */ ++ UTIL_CACHESIZE_REDUCED = 1, ++ /** ++ * An error occured resolving the cache size. You must stop processing. ++ */ ++ UTIL_CACHESIZE_ERROR = 2, ++} util_cachesize_result; + /** +- * Determine if the requested cachesize will exceed the system memory limits causing an out of memory condition ++ * Determine if the requested cachesize will exceed the system memory limits causing an out of memory condition. You must ++ * check the result before proceeding to correctly use the cache. + * ++ * \param mi. The system memory infomation. You should retrieve this with spal_meminfo_get(), and destroy it after use. + * \param cachesize. The requested allocation. If this value is greater than the memory available, this value will be REDUCED to be valid. + * +- * \return 0 if the size is "sane". 1 if the value will cause OOM and has been REDUCED ++ * \return util_cachesize_result. ++ * \sa util_cachesize_result, spal_meminfo_get + */ +-int util_is_cachesize_sane(size_t *cachesize); ++util_cachesize_result util_is_cachesize_sane(slapi_pal_meminfo *mi, size_t *cachesize); + + /** + * Retrieve the number of threads the server should run with based on this hardware. +diff --git a/ldap/servers/slapd/slapi_pal.c b/ldap/servers/slapd/slapi_pal.c +new file mode 100644 +index 0000000..91576ca +--- /dev/null ++++ b/ldap/servers/slapd/slapi_pal.c +@@ -0,0 +1,311 @@ ++/** 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 **/ ++ ++/* ++ * Implementation of functions to abstract from platform ++ * specific issues. ++ */ ++ ++/* Provide ch_malloc etc. */ ++#include ++/* Provide slapi_log_err macro wrapper */ ++#include ++#include ++ ++/* Assert macros */ ++#include ++/* Access errno */ ++#include ++ ++/* For getpagesize */ ++#include ++ ++/* For rlimit */ ++#include ++#include ++ ++#ifdef OS_solaris ++#include ++#endif ++ ++#if defined ( hpux ) ++#include ++#endif ++ ++static int_fast32_t ++_spal_rlimit_get(int resource, uint64_t *soft_limit, uint64_t *hard_limit) { ++ struct rlimit rl = {0}; ++ ++ if (getrlimit(resource, &rl) != 0) { ++ int errsrv = errno; ++ slapi_log_err(SLAPI_LOG_ERR, "_spal_rlimit_mem_get", "Failed to access system resource limits %d\n", errsrv); ++ return 1; ++ } ++ ++ if (rl.rlim_cur != RLIM_INFINITY) { ++ *soft_limit = (uint64_t)rl.rlim_cur; ++ } ++ if (rl.rlim_max != RLIM_INFINITY) { ++ *hard_limit = (uint64_t)rl.rlim_max; ++ } ++ ++ return 0; ++} ++ ++ ++#ifdef LINUX ++static int_fast32_t ++_spal_uint64_t_file_get(char *name, char *prefix, uint64_t *dest) { ++ FILE *f; ++ char s[40] = {0}; ++ size_t prefix_len = 0; ++ ++ if (prefix != NULL) { ++ prefix_len = strlen(prefix); ++ } ++ ++ /* Make sure we can fit into our buffer */ ++ assert((prefix_len + 20) < 39); ++ ++ f = fopen(name, "r"); ++ if (!f) { /* fopen failed */ ++ int errsrv = errno; ++ slapi_log_err(SLAPI_LOG_ERR,"_spal_get_uint64_t_file", "Unable to open file \"%s\". errno=%d\n", name, errsrv); ++ return 1; ++ } ++ ++ int_fast32_t retval = 0; ++ while (! feof(f)) { ++ if (!fgets(s, 39, f)) { ++ retval = 1; ++ break; /* error or eof */ ++ } ++ if (feof(f)) { ++ retval = 1; ++ break; ++ } ++ if (prefix_len > 0 && strncmp(s, prefix, prefix_len) == 0) { ++ sscanf(s + prefix_len, "%"SCNu64, dest); ++ break; ++ } else if (prefix_len == 0) { ++ sscanf(s, "%"SCNu64, dest); ++ break; ++ } ++ } ++ fclose(f); ++ return retval; ++} ++ ++ ++ ++slapi_pal_meminfo * ++spal_meminfo_get() { ++ slapi_pal_meminfo *mi = (slapi_pal_meminfo *)slapi_ch_calloc(1, sizeof(slapi_pal_meminfo)); ++ ++ mi->pagesize_bytes = getpagesize(); ++ ++ /* ++ * We have to compare values from a number of sources to ensure we have ++ * the correct result. ++ */ ++ ++ char f_proc_status[30] = {0}; ++ sprintf(f_proc_status, "/proc/%d/status", getpid()); ++ char *p_vmrss = "VmRSS:"; ++ uint64_t vmrss = 0; ++ ++ if (_spal_uint64_t_file_get(f_proc_status, p_vmrss, &vmrss)) { ++ slapi_log_err(SLAPI_LOG_ERR, "spal_meminfo_get", "Unable to retrieve vmrss\n"); ++ } ++ ++ /* vmrss is in kb, so convert to bytes */ ++ vmrss = vmrss * 1024; ++ ++ uint64_t rl_mem_soft = 0; ++ uint64_t rl_mem_hard = 0; ++ uint64_t rl_mem_soft_avail = 0; ++ ++ if (_spal_rlimit_get(RLIMIT_AS, &rl_mem_soft, &rl_mem_hard)) { ++ slapi_log_err(SLAPI_LOG_ERR, "spal_meminfo_get", "Unable to retrieve memory rlimit\n"); ++ } ++ ++ if (rl_mem_soft != 0 && vmrss != 0 && rl_mem_soft > vmrss) { ++ rl_mem_soft_avail = rl_mem_soft - vmrss; ++ } ++ ++ char *f_meminfo = "/proc/meminfo"; ++ char *p_memtotal = "MemTotal:"; ++ char *p_memavail = "MemAvailable:"; ++ ++ uint64_t memtotal = 0; ++ uint64_t memavail = 0; ++ ++ if (_spal_uint64_t_file_get(f_meminfo, p_memtotal, &memtotal)) { ++ slapi_log_err(SLAPI_LOG_ERR, "spal_meminfo_get", "Unable to retrieve %s : %s\n", f_meminfo, p_memtotal); ++ } ++ ++ if (_spal_uint64_t_file_get(f_meminfo, p_memavail, &memavail)) { ++ slapi_log_err(SLAPI_LOG_ERR, "spal_meminfo_get", "Unable to retrieve %s : %s\n", f_meminfo, p_memavail); ++ } ++ ++ /* Both memtotal and memavail are in kb */ ++ memtotal = memtotal * 1024; ++ memavail = memavail * 1024; ++ ++ /* If it's possible, get our cgroup info */ ++ uint64_t cg_mem_soft = 0; ++ uint64_t cg_mem_hard = 0; ++ uint64_t cg_mem_usage = 0; ++ uint64_t cg_mem_soft_avail = 0; ++ ++ char *f_cg_soft = "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"; ++ char *f_cg_hard = "/sys/fs/cgroup/memory/memory.limit_in_bytes"; ++ char *f_cg_usage = "/sys/fs/cgroup/memory/memory.usage_in_bytes"; ++ ++ if (_spal_uint64_t_file_get(f_cg_soft, NULL, &cg_mem_soft)) { ++ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to retrieve %s. There may be no cgroup support on this platform\n", f_cg_soft); ++ } ++ ++ if (_spal_uint64_t_file_get(f_cg_hard, NULL, &cg_mem_hard)) { ++ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to retrieve %s. There may be no cgroup support on this platform\n", f_cg_hard); ++ } ++ ++ if (_spal_uint64_t_file_get(f_cg_usage, NULL, &cg_mem_usage)) { ++ slapi_log_err(SLAPI_LOG_WARNING, "spal_meminfo_get", "Unable to retrieve %s. There may be no cgroup support on this platform\n", f_cg_hard); ++ } ++ ++ /* ++ * In some conditions, like docker, we only have a *hard* limit set. ++ * This obviously breaks our logic, so we need to make sure we correct this ++ */ ++ ++ if (cg_mem_hard != 0 && cg_mem_soft != 0 && cg_mem_hard < cg_mem_soft) { ++ /* Right, we only have a hard limit. Impose a 10% watermark. */ ++ cg_mem_soft = cg_mem_hard * 0.9; ++ } ++ ++ if (cg_mem_soft != 0 && cg_mem_usage != 0 && cg_mem_soft > cg_mem_usage) { ++ cg_mem_soft_avail = cg_mem_soft - cg_mem_usage; ++ } ++ ++ ++ /* Now, compare the values and make a choice to which is provided */ ++ ++ /* Process consumed memory */ ++ mi->process_consumed_bytes = vmrss; ++ mi->process_consumed_pages = vmrss / mi->pagesize_bytes; ++ ++ /* System Total memory */ ++ /* If we have a memtotal, OR if no memtotal but rlimit */ ++ if (rl_mem_hard != 0 && ++ ((memtotal != 0 && rl_mem_hard < memtotal) || memtotal == 0) && ++ ((cg_mem_hard != 0 && rl_mem_hard < cg_mem_hard) || cg_mem_hard == 0) ++ ) ++ { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_total_bytes - using rlimit\n"); ++ mi->system_total_bytes = rl_mem_hard; ++ mi->system_total_pages = rl_mem_hard / mi->pagesize_bytes; ++ } else if (cg_mem_hard != 0 && ((memtotal != 0 && cg_mem_hard < memtotal) || memtotal == 0)) { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_total_bytes - using cgroup\n"); ++ mi->system_total_bytes = cg_mem_hard; ++ mi->system_total_pages = cg_mem_hard / mi->pagesize_bytes; ++ } else if (memtotal != 0) { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_total_bytes - using memtotal\n"); ++ mi->system_total_bytes = memtotal; ++ mi->system_total_pages = memtotal / mi->pagesize_bytes; ++ } else { ++ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "Unable to determine system total memory!\n"); ++ spal_meminfo_destroy(mi); ++ return NULL; ++ } ++ ++ /* System Available memory */ ++ ++ if (rl_mem_soft_avail != 0 && ++ ((memavail != 0 && (rl_mem_soft_avail) < memavail) || memavail == 0) && ++ ((cg_mem_soft_avail != 0 && rl_mem_soft_avail < cg_mem_soft_avail) || cg_mem_soft_avail == 0) ++ ) ++ { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_available_bytes - using rlimit\n"); ++ mi->system_available_bytes = rl_mem_soft_avail; ++ mi->system_available_pages = rl_mem_soft_avail / mi->pagesize_bytes; ++ } else if (cg_mem_soft_avail != 0 && ((memavail != 0 && (cg_mem_soft_avail) < memavail) || memavail == 0)) { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_available_bytes - using cgroup\n"); ++ mi->system_available_bytes = cg_mem_soft_avail; ++ mi->system_available_pages = cg_mem_soft_avail / mi->pagesize_bytes; ++ } else if (memavail != 0) { ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "system_available_bytes - using memavail\n"); ++ mi->system_available_bytes = memavail; ++ mi->system_available_pages = memavail / mi->pagesize_bytes; ++ } else { ++ slapi_log_err(SLAPI_LOG_CRIT, "spal_meminfo_get", "Unable to determine system available memory!\n"); ++ spal_meminfo_destroy(mi); ++ return NULL; ++ } ++ ++ slapi_log_err(SLAPI_LOG_TRACE, "spal_meminfo_get", "{pagesize_bytes = %"PRIu64", system_total_pages = %"PRIu64", system_total_bytes = %"PRIu64", process_consumed_pages = %"PRIu64", process_consumed_bytes = %"PRIu64", system_available_pages = %"PRIu64", system_available_bytes = %"PRIu64"},\n", ++ mi->pagesize_bytes, mi->system_total_pages, mi->system_total_bytes, mi->process_consumed_pages, mi->process_consumed_bytes, mi->system_available_pages, mi->system_available_bytes); ++ ++ return mi; ++} ++ ++ ++#endif ++ ++#ifdef OS_solaris ++uint64_t ++_spal_solaris_resident_pages_get() { ++ uint64_t procpages = 0; ++ struct prpsinfo psi = {0}; ++ char fn[40]; ++ int fd; ++ ++ sprintf(fn, "/proc/%d", getpid()); ++ fd = open(fn, O_RDONLY); ++ if (fd >= 0) { ++ if (ioctl(fd, PIOCPSINFO, (void *)&psi) == 0) { ++ procpages = (uint64_t)psi.pr_size; ++ } ++ close(fd); ++ } ++ return procpages; ++} ++ ++slapi_pal_meminfo * ++spal_meminfo_get() { ++ slapi_pal_meminfo *mi = (slapi_pal_meminfo *)slapi_ch_calloc(1, sizeof(slapi_pal_meminfo)); ++ ++ uint64_t rl_mem_soft = 0; ++ uint64_t rl_mem_hard = 0; ++ ++ if (_spal_rlimit_get(RLIMIT_AS, &rl_mem_soft, &rl_mem_hard)) { ++ slapi_log_err(SLAPI_LOG_ERR, "spal_meminfo_get", "Unable to retrieve memory rlimit\n"); ++ } ++ ++ mi->pagesize_bytes = sysconf(_SC_PAGESIZE); ++ mi->system_total_pages = sysconf(_SC_PHYS_PAGES); ++ mi->system_total_bytes = mi->system_total_pages * mi->pagesize_bytes; ++ mi->system_available_bytes = rl_mem_soft; ++ if (rl_mem_soft != 0) { ++ mi->system_available_pages = rl_mem_soft / mi->pagesize_bytes; ++ } ++ mi->process_consumed_pages = _spal_solaris_resident_pages_get(); ++ mi->process_consumed_bytes = mi->process_consumed_pages * mi->pagesize_bytes; ++ ++ return mi; ++ ++} ++#endif ++ ++#ifdef HPUX ++#endif ++ ++void ++spal_meminfo_destroy(slapi_pal_meminfo *mi) { ++ slapi_ch_free((void **)&mi); ++} +diff --git a/ldap/servers/slapd/slapi_pal.h b/ldap/servers/slapd/slapi_pal.h +new file mode 100644 +index 0000000..cb61d84 +--- /dev/null ++++ b/ldap/servers/slapd/slapi_pal.h +@@ -0,0 +1,62 @@ ++/** 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 **/ ++ ++/* ++ * Header for the slapi platform abstraction layer. ++ * ++ * This implements a number of functions that help to provide vendor ++ * neutral requests. Candidates for this are memory, thread, disk size ++ * and other operations. ++ * ++ * Basically anywhere you see a "ifdef PLATFORM" is a candidate ++ * for this. ++ */ ++ ++#pragma once ++ ++#include ++ ++#ifdef HAVE_INTTYPES_H ++#include ++#else ++#error Need to define portable format macros such as PRIu64 ++#endif /* HAVE_INTTYPES_H */ ++ ++/** ++ * Structure that contains our system memory information in bytes and pages. ++ * ++ */ ++typedef struct _slapi_pal_meminfo { ++ uint64_t pagesize_bytes; ++ uint64_t system_total_pages; ++ uint64_t system_total_bytes; ++ uint64_t process_consumed_pages; ++ uint64_t process_consumed_bytes; ++ /* This value may be limited by cgroup or others. */ ++ uint64_t system_available_pages; ++ uint64_t system_available_bytes; ++} slapi_pal_meminfo; ++ ++/** ++ * Allocate and returne a populated memory info structure. This will be NULL ++ * on error, or contain a structure populated with platform information on ++ * success. You should free this with spal_meminfo_destroy. ++ * ++ * \return slapi_pal_meminfo * pointer to structure containing data, or NULL. ++ */ ++slapi_pal_meminfo * spal_meminfo_get(); ++ ++/** ++ * Destroy an allocated memory info structure. The caller is responsible for ++ * ensuring this is called. ++ * ++ * \param mi the allocated slapi_pal_meminfo structure from spal_meminfo_get(); ++ */ ++void spal_meminfo_destroy(slapi_pal_meminfo *mi); ++ ++ +diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c +index b0c873d..21043d9 100644 +--- a/ldap/servers/slapd/snmp_collator.c ++++ b/ldap/servers/slapd/snmp_collator.c +@@ -711,7 +711,7 @@ static void + add_counter_to_value(Slapi_Entry *e, const char *type, PRUint64 countervalue) + { + char value[40]; +- snprintf(value,sizeof(value),"%" NSPRIu64, countervalue); ++ snprintf(value,sizeof(value),"%" PRIu64, countervalue); + slapi_entry_attr_set_charptr( e, type, value); + } + +diff --git a/ldap/servers/slapd/unbind.c b/ldap/servers/slapd/unbind.c +index fd44249..92dd905 100644 +--- a/ldap/servers/slapd/unbind.c ++++ b/ldap/servers/slapd/unbind.c +@@ -49,7 +49,7 @@ do_unbind( Slapi_PBlock *pb ) + * UnBindRequest ::= NULL + */ + if ( ber_get_null( ber ) == LBER_ERROR ) { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d UNBIND," ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d UNBIND," + " decoding error: UnBindRequest not null\n", + pb->pb_conn->c_connid, operation->o_opid ); + /* LDAPv3 does not allow a response to an unbind... so just return. */ +@@ -64,7 +64,7 @@ do_unbind( Slapi_PBlock *pb ) + * MUST ignore the criticality field of controls + */ + if ( (err = get_ldapmessage_controls_ext( pb, ber, NULL, ignore_criticality )) != 0 ) { +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d UNBIND," ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d UNBIND," + " error processing controls - error %d (%s)\n", + pb->pb_conn->c_connid, operation->o_opid, + err, ldap_err2string( err )); +@@ -79,7 +79,7 @@ do_unbind( Slapi_PBlock *pb ) + + /* ONREPL - plugins should be called and passed bind dn and, possibly, other data */ + +- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d UNBIND\n", ++ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d UNBIND\n", + pb->pb_conn->c_connid, operation->o_opid ); + + /* pass the unbind to all backends */ +diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c +index 48fa3c4..012e83d 100644 +--- a/ldap/servers/slapd/util.c ++++ b/ldap/servers/slapd/util.c +@@ -40,20 +40,8 @@ + #define FILTER_BUF 128 /* initial buffer size for attr value */ + #define BUF_INCR 16 /* the amount to increase the FILTER_BUF once it fills up */ + +-/* Used by our util_info_sys_pages function +- * +- * platforms supported so far: +- * Solaris, Linux, Windows +- */ +-#ifdef OS_solaris +-#include +-#endif +-#ifdef LINUX +-#include +-#endif +-#if defined ( hpux ) +-#include +-#endif ++/* slapi-private contains the pal. */ ++#include + + static int special_filename(unsigned char c) + { +@@ -1471,361 +1459,25 @@ slapi_uniqueIDRdnSize(void) + return util_uniqueidlen; + } + +- +-/** +- * Get the virtual memory size as defined by system rlimits. +- * +- * \return size_t bytes available +- */ +-static size_t util_getvirtualmemsize(void) +-{ +- struct rlimit rl; +- /* the maximum size of a process's total available memory, in bytes */ +- if (getrlimit(RLIMIT_AS, &rl) != 0) { +- /* We received an error condition. There are a number of possible +- * reasons we have have gotten here, but most likely is EINVAL, where +- * rlim->rlim_cur was greater than rlim->rlim_max. +- * As a result, we should return a 0, to tell the system we can't alloc +- * memory. +- */ +- int errsrv = errno; +- slapi_log_err(SLAPI_LOG_ERR,"util_getvirtualmemsize", +- "getrlimit returned non-zero. errno=%u\n", errsrv); +- return 0; +- } +- return rl.rlim_cur; +-} +- +-/* pages = number of pages of physical ram on the machine (corrected for 32-bit build on 64-bit machine). +- * procpages = pages currently used by this process (or working set size, sometimes) +- * availpages = some notion of the number of pages 'free'. Typically this number is not useful. +- */ +-int util_info_sys_pages(size_t *pagesize, size_t *pages, size_t *procpages, size_t *availpages) +-{ +- if ((NULL == pagesize) || (NULL == pages) || (NULL == procpages) || (NULL == availpages)) { +- slapi_log_err(SLAPI_LOG_ERR, "util_info_sys_pages", +- "Null return variables are passed. Skip getting the system info.\n"); +- return 1; +- } +- *pagesize = 0; +- *pages = 0; +- *availpages = 0; +- *procpages = 0; +- +-#ifdef OS_solaris +- *pagesize = (int)sysconf(_SC_PAGESIZE); +- *pages = (int)sysconf(_SC_PHYS_PAGES); +- *availpages = util_getvirtualmemsize() / *pagesize; +- /* solaris has THE most annoying way to get this info */ +- { +- struct prpsinfo psi = {0}; +- char fn[40]; +- int fd; +- +- sprintf(fn, "/proc/%d", getpid()); +- fd = open(fn, O_RDONLY); +- if (fd >= 0) { +- if (ioctl(fd, PIOCPSINFO, (void *)&psi) == 0) { +- *procpages = psi.pr_size; +- } +- close(fd); +- } +- } +-#endif +- +-#ifdef LINUX +- { +- /* +- * On linux because of the way that the virtual memory system works, we +- * don't really need to think about other processes, or fighting them. +- * But that's not without quirks. +- * +- * We are given a virtual memory space, represented by vsize (man 5 proc) +- * This space is a "funny number". It's a best effort based system +- * where linux instead of telling us how much memory *actually* exists +- * for us to use, gives us a virtual memory allocation which is the +- * value of ram + swap.... sometimes. Depends on platform. +- * +- * But none of these pages even exist or belong to us on the real system +- * until will malloc them AND write a non-zero to them. +- * +- * The biggest issue with this is that vsize does NOT consider the +- * effect other processes have on the system. So a process can malloc +- * 2 Gig from the host, and our vsize doesn't reflect that until we +- * suddenly can't malloc anything. +- * +- * We can see exactly what we are using inside of the vmm by +- * looking at rss (man 5 proc). This shows us the current actual +- * allocation of memory we are using. This is a good thing. +- * +- * We obviously don't want to have any pages in swap, but sometimes we +- * can't help that: And there is also no guarantee that while we have +- * X bytes in vsize, that we can even allocate any of them. Plus, we +- * don't know if we are about to allocate to swap or not .... or get us +- * killed in a blaze of oom glory. +- * +- * So there are now two strategies avaliable in this function. +- * The first is to blindly accept what the VMM tells us about vsize +- * while we hope and pray that we don't get nailed because we used +- * too much. +- * +- * The other is a more conservative approach: We check vsize from +- * proc/pid/status, and we check /proc/meminfo for freemem +- * Which ever value is "lower" is the upper bound on pages we could +- * potentially allocate: generally, this will be MemAvailable. +- */ +- +- size_t freesize = 0; +- size_t rlimsize = 0; +- +- *pagesize = getpagesize(); +- +- /* Get the amount of freeram, rss */ +- +- FILE *f; +- char fn[40], s[80]; +- +- sprintf(fn, "/proc/%d/status", getpid()); +- f = fopen(fn, "r"); +- if (!f) { /* fopen failed */ +- /* We should probably make noise here! */ +- int errsrv = errno; +- slapi_log_err(SLAPI_LOG_ERR,"util_info_sys_pages", "Unable to open file /proc/%d/status. errno=%u\n", getpid(), errsrv); +- return 1; +- } +- while (! feof(f)) { +- if (!fgets(s, 79, f)) { +- break; /* error or eof */ +- } +- if (feof(f)) { +- break; +- } +- /* VmRSS shows us what we are ACTUALLY using for proc pages +- * Rather than "funny" pages. +- */ +- if (strncmp(s, "VmRSS:", 6) == 0) { +- sscanf(s+6, "%lu", (long unsigned int *)procpages); +- } +- } +- fclose(f); +- +- FILE *fm; +- char *fmn = "/proc/meminfo"; +- fm = fopen(fmn, "r"); +- if (!fm) { +- int errsrv = errno; +- slapi_log_err(SLAPI_LOG_ERR,"util_info_sys_pages", "Unable to open file /proc/meminfo. errno=%u\n", errsrv); +- return 1; +- } +- while (! feof(fm)) { +- if (!fgets(s, 79, fm)) { +- break; /* error or eof */ +- } +- if (feof(fm)) { +- break; +- } +- if (strncmp(s, "MemTotal:", 9) == 0) { +- sscanf(s+9, "%lu", (long unsigned int *)pages); +- } +- if (strncmp(s, "MemAvailable:", 13) == 0) { +- sscanf(s+13, "%lu", (long unsigned int *)&freesize); +- } +- } +- fclose(fm); +- +- +- *pages /= (*pagesize / 1024); +- freesize /= (*pagesize / 1024); +- /* procpages is now in kb not pages... */ +- *procpages /= (*pagesize / 1024); +- +- rlimsize = util_getvirtualmemsize(); +- /* On a 64 bit system, this is uint64 max, but on 32 it's -1 */ +- /* Either way, we should be ignoring it at this point if it's infinite */ +- if (rlimsize != RLIM_INFINITY) { +- /* This is in bytes, make it pages */ +- rlimsize = rlimsize / *pagesize; +- } +- +- /* Pages is the total ram on the system. */ +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "pages=%lu, \n", +- (unsigned long) *pages); +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "using pages for pages \n"); +- +- /* Availpages is how much we *could* alloc. We should take the smallest: +- * - pages +- * - getrlimit (availpages) +- * - freesize +- */ +- if (rlimsize == RLIM_INFINITY) { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "pages=%lu, getrlim=RLIM_INFINITY, freesize=%lu\n", +- (unsigned long)*pages, (unsigned long)freesize); +- } else { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "pages=%lu, getrlim=%lu, freesize=%lu\n", +- (unsigned long)*pages, (unsigned long)*availpages, (unsigned long)freesize); +- } +- +- if (rlimsize != RLIM_INFINITY && rlimsize < freesize && rlimsize < *pages && rlimsize > 0) { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "using getrlim for availpages \n"); +- *availpages = rlimsize; +- } else if (freesize < *pages && freesize > 0) { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "using freesize for availpages \n"); +- *availpages = freesize; +- } else { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "using pages for availpages \n"); +- *availpages = *pages; +- } +- +- } +-#endif /* linux */ +- +- +- +-#if defined ( hpux ) +- { +- struct pst_static pst; +- int rval = pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0); +- if (rval < 0) { /* pstat_getstatic failed */ +- return 1; +- } +- *pagesize = pst.page_size; +- *pages = pst.physical_memory; +- *availpages = util_getvirtualmemsize() / *pagesize; +- if (procpages) +- { +-#define BURST (size_t)32 /* get BURST proc info at one time... */ +- struct pst_status psts[BURST]; +- int i, count; +- int idx = 0; /* index within the context */ +- int mypid = getpid(); +- +- *procpages = 0; +- /* loop until count == 0, will occur all have been returned */ +- while ((count = pstat_getproc(psts, sizeof(psts[0]), BURST, idx)) > 0) { +- /* got count (max of BURST) this time. process them */ +- for (i = 0; i < count; i++) { +- if (psts[i].pst_pid == mypid) +- { +- *procpages = (size_t)(psts[i].pst_dsize + psts[i].pst_tsize + psts[i].pst_ssize); +- break; +- } +- } +- if (i < count) +- break; +- +- /* +- * now go back and do it again, using the next index after +- * the current 'burst' +- */ +- idx = psts[count-1].pst_idx + 1; +- } +- } +- } +-#endif +- /* If this is a 32-bit build, it might be running on a 64-bit machine, +- * in which case, if the box has tons of ram, we can end up telling +- * the auto cache code to use more memory than the process can address. +- * so we cap the number returned here. +- */ +-#if defined(__LP64__) || defined (_LP64) +-#else +- { +-#define GIGABYTE (1024*1024*1024) +- size_t one_gig_pages = GIGABYTE / *pagesize; +- if (*pages > (2 * one_gig_pages) ) { +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", +- "More than 2Gbytes physical memory detected. Since this is a 32-bit process, truncating memory size used for auto cache calculations to 2Gbytes\n"); +- *pages = (2 * one_gig_pages); +- } +- } +-#endif +- +- /* This is stupid. If you set %u to %zu to print a size_t, you get literal %zu in your logs +- * So do the filthy cast instead. +- */ +- slapi_log_err(SLAPI_LOG_TRACE,"util_info_sys_pages", "USING pages=%lu, procpages=%lu, availpages=%lu \n", +- (unsigned long)*pages, (unsigned long)*procpages, (unsigned long)*availpages); +- return 0; +- +-} +- +-int util_is_cachesize_sane(size_t *cachesize) ++util_cachesize_result ++util_is_cachesize_sane(slapi_pal_meminfo *mi, uint64_t *cachesize) + { +- size_t pages = 0; +- size_t pagesize = 0; +- size_t procpages = 0; +- size_t availpages = 0; +- +- size_t cachepages = 0; +- +- int issane = 1; +- +- if (util_info_sys_pages(&pagesize, &pages, &procpages, &availpages) != 0) { +- goto out; +- } +-#ifdef LINUX +- /* Linux we calculate availpages correctly, so USE IT */ +- if (!pagesize || !availpages) { +- goto out; +- } +-#else +- if (!pagesize || !pages) { +- goto out; ++ /* Check we have a valid meminfo struct */ ++ if (mi->system_available_bytes == 0) { ++ slapi_log_err(SLAPI_LOG_CRIT, "util_is_cachesize_sane", "Invalid system memory info, can not proceed."); ++ return UTIL_CACHESIZE_ERROR; + } +-#endif +- /* do nothing when we can't get the avail mem */ +- +- +- /* If the requested cache size is larger than the remaining physical memory +- * after the current working set size for this process has been subtracted, +- * then we say that's insane and try to correct. +- */ +- +- cachepages = *cachesize / pagesize; +- slapi_log_err(SLAPI_LOG_TRACE,"util_is_cachesize_sane", "cachesize=%lu / pagesize=%lu \n", +- (unsigned long)*cachesize,(unsigned long)pagesize); +- +-#ifdef LINUX +- /* Linux we calculate availpages correctly, so USE IT */ +- issane = (int)(cachepages <= availpages); +- slapi_log_err(SLAPI_LOG_TRACE,"util_is_cachesize_sane", "cachepages=%lu <= availpages=%lu\n", +- (unsigned long)cachepages,(unsigned long)availpages); + +- if (!issane) { ++ 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. + * the remaining system mem to the cachesize instead, and log a warning + */ +- *cachesize = (size_t)((availpages * 0.75 ) * pagesize); +- /* These are now trace warnings, because it was to confusing to log this *then* kill the request anyway. +- * Instead, we will let the caller worry about the notification, and we'll just use this in debugging and tracing. +- */ +- slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", +- "Available pages %lu, requested pages %lu, pagesize %lu\n", (unsigned long)availpages, (unsigned long)cachepages, (unsigned long)pagesize); +- slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", +- "WARNING adjusted cachesize to %lu\n", (unsigned long)*cachesize); +- } +-#else +- size_t freepages = 0; +- freepages = pages - procpages; +- slapi_log_err(SLAPI_LOG_TRACE,"util_is_cachesize_sane", "pages=%lu - procpages=%lu\n", +- (unsigned long)pages,(unsigned long)procpages); +- +- issane = (int)(cachepages <= freepages); +- slapi_log_err(SLAPI_LOG_TRACE,"util_is_cachesize_sane", "cachepages=%lu <= freepages=%lu\n", +- (unsigned long)cachepages,(unsigned long)freepages); +- +- if (!issane) { +- *cachesize = (size_t)((pages - procpages) * pagesize); +- slapi_log_err(SLAPI_LOG_WARNING, "util_is_cachesize_sane", "WARNING adjusted cachesize to %lu\n", +- (unsigned long )*cachesize); ++ *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; + } +-#endif +-out: +- if (!issane) { +- slapi_log_err(SLAPI_LOG_TRACE,"util_is_cachesize_sane", "WARNING: Cachesize not sane \n"); +- } +- +- return issane; ++ return UTIL_CACHESIZE_VALID; + } + + long +diff --git a/test/libslapd/spal/meminfo.c b/test/libslapd/spal/meminfo.c +new file mode 100644 +index 0000000..776141a +--- /dev/null ++++ b/test/libslapd/spal/meminfo.c +@@ -0,0 +1,54 @@ ++/** 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 **/ ++ ++#include "../../test_slapd.h" ++ ++#include ++#include ++ ++/* ++ * Assert that our meminfo interface in slapi_pal works. ++ */ ++ ++void ++test_libslapd_pal_meminfo(void **state __attribute__((unused))) { ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ assert_true(mi->pagesize_bytes > 0); ++ assert_true(mi->system_total_pages > 0); ++ assert_true(mi->system_total_bytes > 0); ++ assert_true(mi->process_consumed_pages > 0); ++ assert_true(mi->process_consumed_bytes > 0); ++ assert_true(mi->system_available_pages > 0); ++ assert_true(mi->system_available_bytes > 0); ++ spal_meminfo_destroy(mi); ++} ++ ++void ++test_libslapd_util_cachesane(void **state __attribute__((unused))) { ++ slapi_pal_meminfo *mi = spal_meminfo_get(); ++ uint64_t request = 0; ++ mi->system_available_bytes = 0; ++ assert_true(util_is_cachesize_sane(mi, &request) == UTIL_CACHESIZE_ERROR); ++ ++ // Set the values to known quantities ++ request = 50000; ++ mi->system_available_bytes = 99999; ++ assert_true(util_is_cachesize_sane(mi, &request) == UTIL_CACHESIZE_VALID); ++ ++ request = 99999; ++ assert_true(util_is_cachesize_sane(mi, &request) == UTIL_CACHESIZE_VALID); ++ ++ request = 100000; ++ assert_true(util_is_cachesize_sane(mi, &request) == UTIL_CACHESIZE_REDUCED); ++ assert_true(request <= 75000); ++ ++ spal_meminfo_destroy(mi); ++} ++ ++ ++ +diff --git a/test/libslapd/test.c b/test/libslapd/test.c +index 6e1171a..6fa7996 100644 +--- a/test/libslapd/test.c ++++ b/test/libslapd/test.c +@@ -26,6 +26,8 @@ run_libslapd_tests (void) { + cmocka_unit_test(test_libslapd_operation_v3c_target_spec), + cmocka_unit_test(test_libslapd_counters_atomic_usage), + cmocka_unit_test(test_libslapd_counters_atomic_overflow), ++ cmocka_unit_test(test_libslapd_pal_meminfo), ++ cmocka_unit_test(test_libslapd_util_cachesane), + }; + return cmocka_run_group_tests(tests, NULL, NULL); + } +diff --git a/test/test_slapd.h b/test/test_slapd.h +index b8f1aba..50de11b 100644 +--- a/test/test_slapd.h ++++ b/test/test_slapd.h +@@ -42,3 +42,8 @@ void test_libslapd_operation_v3c_target_spec(void **state); + void test_libslapd_counters_atomic_usage(void **state); + void test_libslapd_counters_atomic_overflow(void **state); + ++/* libslapd-pal-meminfo */ ++ ++void test_libslapd_pal_meminfo(void **state); ++void test_libslapd_util_cachesane(void **state); ++ +-- +2.9.3 + diff --git a/SOURCES/0028-Ticket-49038-remove-legacy-replication-change-cleanu.patch b/SOURCES/0028-Ticket-49038-remove-legacy-replication-change-cleanu.patch deleted file mode 100644 index dd889f9..0000000 --- a/SOURCES/0028-Ticket-49038-remove-legacy-replication-change-cleanu.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 2b5b09a7a871d626bb45888f948126732d0893f3 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 4 Oct 2017 12:55:30 -0400 -Subject: [PATCH] Ticket 49038 - remove legacy replication - change cleanup - script precedence - -Description: Bump the cleanup scripts precendance so it happens after the - main plugin upgrade scripts are called. - -https://pagure.io/389-ds-base/issue/49038 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit 1fe2c761103c36090ab67df0271dfdb3012037fb) ---- - Makefile.am | 2 +- - ...{50removeLegacyReplication.ldif => 60removeLegacyReplication.ldif} | 0 - rpm/389-ds-base.spec.in | 4 ++-- - 3 files changed, 3 insertions(+), 3 deletions(-) - rename ldap/admin/src/scripts/{50removeLegacyReplication.ldif => 60removeLegacyReplication.ldif} (100%) - -diff --git a/Makefile.am b/Makefile.am -index 09a6bc296..8834a7819 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -942,7 +942,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \ - ldap/admin/src/scripts/50telexnumbersyntaxplugin.ldif \ - ldap/admin/src/scripts/50guidesyntaxplugin.ldif \ - ldap/admin/src/scripts/50targetuniqueid.ldif \ -- ldap/admin/src/scripts/50removeLegacyReplication.ldif \ -+ ldap/admin/src/scripts/60removeLegacyReplication.ldif \ - ldap/admin/src/scripts/50linkedattrsplugin.ldif \ - ldap/admin/src/scripts/50usnplugin.ldif \ - ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif \ -diff --git a/ldap/admin/src/scripts/50removeLegacyReplication.ldif b/ldap/admin/src/scripts/60removeLegacyReplication.ldif -similarity index 100% -rename from ldap/admin/src/scripts/50removeLegacyReplication.ldif -rename to ldap/admin/src/scripts/60removeLegacyReplication.ldif -diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in -index 1e5c2cfd3..30a1d7d9a 100644 ---- a/rpm/389-ds-base.spec.in -+++ b/rpm/389-ds-base.spec.in -@@ -395,9 +395,9 @@ echo remove pid files . . . >> $output 2>&1 || : - echo upgrading instances . . . >> $output 2>&1 || : - DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"` - if [ -n "$DEBUGPOSTSETUPOPT" ] ; then -- %{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : -+ %{_sbindir}/setup-ds.pl -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : - else -- %{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || : -+ %{_sbindir}/setup-ds.pl -u -s General.UpdateMode=offline >> $output 2>&1 || : - fi - - # restart instances that require it --- -2.13.6 - diff --git a/SOURCES/0029-Ticket-49204-Fix-lower-bounds-on-import-autosize-On-.patch b/SOURCES/0029-Ticket-49204-Fix-lower-bounds-on-import-autosize-On-.patch new file mode 100644 index 0000000..1e28e73 --- /dev/null +++ b/SOURCES/0029-Ticket-49204-Fix-lower-bounds-on-import-autosize-On-.patch @@ -0,0 +1,296 @@ +From 9be74e83539e204e9a56721da5c22bd9abf38195 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0029-Ticket-49454-SSL-Client-Authentication-breaks-in-FIP.patch b/SOURCES/0029-Ticket-49454-SSL-Client-Authentication-breaks-in-FIP.patch deleted file mode 100644 index c46e333..0000000 --- a/SOURCES/0029-Ticket-49454-SSL-Client-Authentication-breaks-in-FIP.patch +++ /dev/null @@ -1,88 +0,0 @@ -From b1dfe53aaf7cb0260286423b9abf7d71f8edd421 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 15 Nov 2017 13:27:58 -0500 -Subject: [PATCH] Ticket 49454 - SSL Client Authentication breaks in FIPS mode - -Bug Description: Replication using SSL Client Auth breaks when FIPS - is enabled. This is because FIPS mode changes the - internal certificate token name. - -Fix Description: If FIPS is enabled grab the token name from the internal - slot instead of using the default hardcoded internal - token name. - -https://pagure.io/389-ds-base/issue/49454 - -Reviewed by: firstyear(Thanks!) - -(cherry picked from commit 6e794a8eff213d49c933f781006e234984160db2) ---- - ldap/servers/slapd/proto-slap.h | 1 + - ldap/servers/slapd/security_wrappers.c | 6 ++++++ - ldap/servers/slapd/ssl.c | 24 +++++++++++++++++------- - 3 files changed, 24 insertions(+), 7 deletions(-) - -diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h -index 4a30def8b..3b7ab53b2 100644 ---- a/ldap/servers/slapd/proto-slap.h -+++ b/ldap/servers/slapd/proto-slap.h -@@ -1130,6 +1130,7 @@ PRBool slapd_pk11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type); - PK11SymKey *slapd_pk11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags, PRBool isPerm); - PK11SymKey *slapd_pk11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx); - CK_MECHANISM_TYPE slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECItem *pwitem); -+char *slapd_PK11_GetTokenName(PK11SlotInfo *slot); - - /* - * start_tls_extop.c -diff --git a/ldap/servers/slapd/security_wrappers.c b/ldap/servers/slapd/security_wrappers.c -index bec28d2f3..41fe03608 100644 ---- a/ldap/servers/slapd/security_wrappers.c -+++ b/ldap/servers/slapd/security_wrappers.c -@@ -401,3 +401,9 @@ slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECIte - { - return PK11_GetPBECryptoMechanism(algid, params, pwitem); - } -+ -+char * -+slapd_PK11_GetTokenName(PK11SlotInfo *slot) -+{ -+ return PK11_GetTokenName(slot); -+} -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index efe32d5d0..52ac7ea9f 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -2365,13 +2365,23 @@ slapd_SSL_client_auth(LDAP *ld) - ssltoken = slapi_entry_attr_get_charptr(entry, "nsssltoken"); - if (ssltoken && personality) { - if (!PL_strcasecmp(ssltoken, "internal") || -- !PL_strcasecmp(ssltoken, "internal (software)")) { -- -- /* Translate config internal name to more -- * readable form. Certificate name is just -- * the personality for internal tokens. -- */ -- token = slapi_ch_strdup(internalTokenName); -+ !PL_strcasecmp(ssltoken, "internal (software)")) -+ { -+ if ( slapd_pk11_isFIPS() ) { -+ /* -+ * FIPS mode changes the internal token name, so we need to -+ * grab the new token name from the internal slot. -+ */ -+ PK11SlotInfo *slot = slapd_pk11_getInternalSlot(); -+ token = slapi_ch_strdup(slapd_PK11_GetTokenName(slot)); -+ PK11_FreeSlot(slot); -+ } else { -+ /* -+ * Translate config internal name to more readable form. -+ * Certificate name is just the personality for internal tokens. -+ */ -+ token = slapi_ch_strdup(internalTokenName); -+ } - #if defined(USE_OPENLDAP) - /* openldap needs tokenname:certnick */ - PR_snprintf(cert_name, sizeof(cert_name), "%s:%s", token, personality); --- -2.13.6 - diff --git a/SOURCES/0030-Ticket-49231-fix-sasl-mech-handling.patch b/SOURCES/0030-Ticket-49231-fix-sasl-mech-handling.patch new file mode 100644 index 0000000..8d5d46f --- /dev/null +++ b/SOURCES/0030-Ticket-49231-fix-sasl-mech-handling.patch @@ -0,0 +1,328 @@ +From 88a0ce3c3f89244a77dfa618c8a5064bda30f376 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0030-Ticket-49435-Fix-NS-race-condition-on-loaded-test-sy.patch b/SOURCES/0030-Ticket-49435-Fix-NS-race-condition-on-loaded-test-sy.patch deleted file mode 100644 index 771963c..0000000 --- a/SOURCES/0030-Ticket-49435-Fix-NS-race-condition-on-loaded-test-sy.patch +++ /dev/null @@ -1,1029 +0,0 @@ -From 04605da5c813ffc818d874ae0a14790c166d792d Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Mon, 6 Nov 2017 08:56:01 +1000 -Subject: [PATCH] Ticket 49435 - Fix NS race condition on loaded test systems - -Bug Description: During a test run, on a heavily loaded systems -some events would time out before they could occur correctly. - -Fix Description: Change the structure of events to mitigate -a deref performance hit, and add a ns_job_wait conditional -that allows blocking on a job to complete so that tests do not -require time based checks. - -https://pagure.io/389-ds-base/issue/49435 - -Author: wibrown - -Review by: mreynolds (Thanks!) ---- - src/nunc-stans/include/nunc-stans.h | 12 +++ - src/nunc-stans/ns/ns_event_fw.h | 3 +- - src/nunc-stans/ns/ns_thrpool.c | 175 +++++++++++++++++++++-------------- - src/nunc-stans/test/test_nuncstans.c | 156 ++++++++++++++++++------------- - 4 files changed, 209 insertions(+), 137 deletions(-) - -diff --git a/src/nunc-stans/include/nunc-stans.h b/src/nunc-stans/include/nunc-stans.h -index 386a8d283..192e38ec3 100644 ---- a/src/nunc-stans/include/nunc-stans.h -+++ b/src/nunc-stans/include/nunc-stans.h -@@ -77,6 +77,10 @@ typedef enum _ns_result_t { - * This occurs when a lower level OS issue occurs, generally thread related. - */ - NS_THREAD_FAILURE = 5, -+ /** -+ * The job is being deleted -+ */ -+ NS_DELETING = 6, - } ns_result_t; - - /** -@@ -837,6 +841,14 @@ ns_job_type_t ns_job_get_output_type(struct ns_job_t *job); - ns_result_t ns_job_set_done_cb(struct ns_job_t *job, ns_job_func_t func); - - /** -+ * Block until a job is completed. This returns the next state of the job as as a return. -+ * -+ * \param job The job to set the callback for. -+ * \retval ns_job_state_t The next state the job will move to. IE, WAITING, DELETED, ARMED. -+ */ -+ns_result_t ns_job_wait(struct ns_job_t *job); -+ -+/** - * Creates a new thread pool - * - * Must be called with a struct ns_thrpool_config that has been -diff --git a/src/nunc-stans/ns/ns_event_fw.h b/src/nunc-stans/ns/ns_event_fw.h -index 436b28269..88997b24d 100644 ---- a/src/nunc-stans/ns/ns_event_fw.h -+++ b/src/nunc-stans/ns/ns_event_fw.h -@@ -80,7 +80,8 @@ typedef enum _ns_job_state { - interface between the app/thread pool/event framework */ - typedef struct ns_job_t - { -- pthread_mutex_t *monitor; -+ pthread_mutex_t monitor; -+ pthread_cond_t notify; - struct ns_thrpool_t *tp; - ns_job_func_t func; - struct ns_job_data_t *data; -diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c -index 2ad0bd799..1d8bb03f1 100644 ---- a/src/nunc-stans/ns/ns_thrpool.c -+++ b/src/nunc-stans/ns/ns_thrpool.c -@@ -214,7 +214,7 @@ job_queue_cleanup(void *arg) - static void - internal_ns_job_done(ns_job_t *job) - { -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "internal_ns_job_done %x state %d moving to NS_JOB_DELETED\n", job, job->state); - #endif -@@ -239,9 +239,9 @@ internal_ns_job_done(ns_job_t *job) - job->done_cb(job); - } - -- pthread_mutex_unlock(job->monitor); -- pthread_mutex_destroy(job->monitor); -- ns_free(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); -+ pthread_mutex_destroy(&(job->monitor)); -+ pthread_cond_destroy(&(job->notify)); - - ns_free(job); - } -@@ -250,7 +250,7 @@ internal_ns_job_done(ns_job_t *job) - static void - internal_ns_job_rearm(ns_job_t *job) - { -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state == NS_JOB_NEEDS_ARM); - /* Don't think I need to check persistence here, it could be the first arm ... */ - #ifdef DEBUG -@@ -267,7 +267,7 @@ internal_ns_job_rearm(ns_job_t *job) - /* Prevents an un-necessary queue / dequeue to the event_q */ - work_q_notify(job); - } -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - } - - static void -@@ -281,7 +281,7 @@ work_job_execute(ns_job_t *job) - * DELETED! Crashes abound, you have been warned ... - */ - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "work_job_execute %x state %d moving to NS_JOB_RUNNING\n", job, job->state); - #endif -@@ -303,7 +303,12 @@ work_job_execute(ns_job_t *job) - #ifdef DEBUG - ns_log(LOG_DEBUG, "work_job_execute %x state %d job func complete, sending to job_done...\n", job, job->state); - #endif -- pthread_mutex_unlock(job->monitor); -+ /* -+ * Let waiters know we are done, they'll pick up once -+ * we unlock. -+ */ -+ pthread_cond_signal(&(job->notify)); -+ pthread_mutex_unlock(&(job->monitor)); - internal_ns_job_done(job); - /* MUST NOT ACCESS JOB AGAIN.*/ - } else if (job->state == NS_JOB_NEEDS_ARM) { -@@ -311,7 +316,8 @@ work_job_execute(ns_job_t *job) - ns_log(LOG_DEBUG, "work_job_execute %x state %d job func complete, sending to rearm...\n", job, job->state); - #endif - /* Rearm the job! */ -- pthread_mutex_unlock(job->monitor); -+ /* We *don't* notify here because we ARE NOT done! */ -+ pthread_mutex_unlock(&(job->monitor)); - internal_ns_job_rearm(job); - } else { - #ifdef DEBUG -@@ -321,7 +327,12 @@ work_job_execute(ns_job_t *job) - PR_ASSERT(!NS_JOB_IS_PERSIST(job->job_type)); - /* We are now idle, set waiting. */ - job->state = NS_JOB_WAITING; -- pthread_mutex_unlock(job->monitor); -+ /* -+ * Let waiters know we are done, they'll pick up once -+ * we unlock. -+ */ -+ pthread_cond_signal(&(job->notify)); -+ pthread_mutex_unlock(&(job->monitor)); - } - /* MUST NOT ACCESS JOB AGAIN */ - } -@@ -338,7 +349,7 @@ static void - work_q_notify(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "work_q_notify %x state %d\n", job, job->state); - #endif -@@ -346,12 +357,12 @@ work_q_notify(ns_job_t *job) - if (job->state != NS_JOB_ARMED) { - /* Maybe we should return some error here? */ - ns_log(LOG_ERR, "work_q_notify %x state %d is not ARMED, cannot queue!\n", job, job->state); -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return; - } - /* MUST NOT ACCESS job after enqueue. So we stash tp.*/ - ns_thrpool_t *ltp = job->tp; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - sds_lqueue_enqueue(ltp->work_q, (void *)job); - pthread_mutex_lock(&(ltp->work_q_lock)); - pthread_cond_signal(&(ltp->work_q_cv)); -@@ -411,13 +422,13 @@ static void - update_event(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "update_event %x state %d\n", job, job->state); - #endif - PR_ASSERT(job->state == NS_JOB_NEEDS_DELETE || job->state == NS_JOB_ARMED); - if (job->state == NS_JOB_NEEDS_DELETE) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - internal_ns_job_done(job); - return; - } else if (NS_JOB_IS_IO(job->job_type) || job->ns_event_fw_fd) { -@@ -426,7 +437,7 @@ update_event(ns_job_t *job) - } else { - job->tp->ns_event_fw->ns_event_fw_mod_io(job->tp->ns_event_fw_ctx, job); - } -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - /* We need these returns to prevent a race on the next else if condition when we release job->monitor */ - return; - } else if (NS_JOB_IS_TIMER(job->job_type) || job->ns_event_fw_time) { -@@ -435,7 +446,7 @@ update_event(ns_job_t *job) - } else { - job->tp->ns_event_fw->ns_event_fw_mod_timer(job->tp->ns_event_fw_ctx, job); - } -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return; - } else if (NS_JOB_IS_SIGNAL(job->job_type) || job->ns_event_fw_sig) { - if (!job->ns_event_fw_sig) { -@@ -443,15 +454,15 @@ update_event(ns_job_t *job) - } else { - job->tp->ns_event_fw->ns_event_fw_mod_signal(job->tp->ns_event_fw_ctx, job); - } -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return; - } else { - /* It's a "run now" job. */ - if (NS_JOB_IS_THREAD(job->job_type)) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - work_q_notify(job); - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - event_q_notify(job); - } - } -@@ -602,14 +613,14 @@ event_cb(ns_job_t *job) - */ - - /* There is no guarantee this won't be called once we start to enter the shutdown, especially with timers .... */ -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - - PR_ASSERT(job->state == NS_JOB_ARMED || job->state == NS_JOB_NEEDS_DELETE); - if (job->state == NS_JOB_ARMED && NS_JOB_IS_THREAD(job->job_type)) { - #ifdef DEBUG - ns_log(LOG_DEBUG, "event_cb %x state %d threaded, send to work_q\n", job, job->state); - #endif -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - work_q_notify(job); - } else if (job->state == NS_JOB_NEEDS_DELETE) { - #ifdef DEBUG -@@ -620,14 +631,14 @@ event_cb(ns_job_t *job) - * It's here because it's been QUEUED for deletion and *may* be coming - * from the thrpool destroy thread! - */ -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - - } else { - #ifdef DEBUG - ns_log(LOG_DEBUG, "event_cb %x state %d non-threaded, execute right meow\n", job, job->state); - #endif - /* Not threaded, execute now! */ -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - work_job_execute(job); - /* MUST NOT ACCESS JOB FROM THIS POINT */ - } -@@ -682,12 +693,12 @@ static ns_job_t * - new_ns_job(ns_thrpool_t *tp, PRFileDesc *fd, ns_job_type_t job_type, ns_job_func_t func, struct ns_job_data_t *data) - { - ns_job_t *job = ns_calloc(1, sizeof(ns_job_t)); -- job->monitor = ns_calloc(1, sizeof(pthread_mutex_t)); - - pthread_mutexattr_t *monitor_attr = ns_calloc(1, sizeof(pthread_mutexattr_t)); - pthread_mutexattr_init(monitor_attr); - pthread_mutexattr_settype(monitor_attr, PTHREAD_MUTEX_RECURSIVE); -- assert(pthread_mutex_init(job->monitor, monitor_attr) == 0); -+ assert(pthread_mutex_init(&(job->monitor), monitor_attr) == 0); -+ assert(pthread_cond_init(&(job->notify), NULL) == 0); - ns_free(monitor_attr); - - job->tp = tp; -@@ -746,14 +757,14 @@ ns_job_done(ns_job_t *job) - /* Get the shutdown state ONCE at the start, atomically */ - int32_t shutdown_state = ns_thrpool_is_shutdown(job->tp); - -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - - if (job->state == NS_JOB_NEEDS_DELETE || job->state == NS_JOB_DELETED) { - /* Just return if the job has been marked for deletion */ - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> %x state %d return early\n", job, shutdown_state, job->state); - #endif -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_SUCCESS; - } - -@@ -762,7 +773,7 @@ ns_job_done(ns_job_t *job) - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d failed to mark as done\n", job, job->state); - #endif -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_INVALID_STATE; - } - -@@ -773,13 +784,13 @@ ns_job_done(ns_job_t *job) - ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d setting to async NS_JOB_NEEDS_DELETE\n", job, job->state); - #endif - job->state = NS_JOB_NEEDS_DELETE; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - } else if (!shutdown_state) { - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_job_done %x tp shutdown -> false state %d setting NS_JOB_NEEDS_DELETE and queuing\n", job, job->state); - #endif - job->state = NS_JOB_NEEDS_DELETE; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - event_q_notify(job); - } else { - #ifdef DEBUG -@@ -787,7 +798,7 @@ ns_job_done(ns_job_t *job) - #endif - job->state = NS_JOB_NEEDS_DELETE; - /* We are shutting down, just remove it! */ -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - internal_ns_job_done(job); - } - return NS_SUCCESS; -@@ -849,12 +860,12 @@ ns_add_io_job(ns_thrpool_t *tp, PRFileDesc *fd, ns_job_type_t job_type, ns_job_f - return NS_ALLOCATION_FAILURE; - } - -- pthread_mutex_lock(_job->monitor); -+ pthread_mutex_lock(&(_job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_add_io_job state %d moving to NS_JOB_ARMED\n", (_job)->state); - #endif - _job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(_job->monitor); -+ pthread_mutex_unlock(&(_job->monitor)); - internal_ns_job_rearm(_job); - - /* fill in a pointer to the job for the caller if requested */ -@@ -889,12 +900,12 @@ ns_add_timeout_job(ns_thrpool_t *tp, struct timeval *tv, ns_job_type_t job_type, - return NS_ALLOCATION_FAILURE; - } - -- pthread_mutex_lock(_job->monitor); -+ pthread_mutex_lock(&(_job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_add_timeout_job state %d moving to NS_JOB_ARMED\n", (_job)->state); - #endif - _job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(_job->monitor); -+ pthread_mutex_unlock(&(_job->monitor)); - internal_ns_job_rearm(_job); - - /* fill in a pointer to the job for the caller if requested */ -@@ -944,14 +955,14 @@ ns_add_io_timeout_job(ns_thrpool_t *tp, PRFileDesc *fd, struct timeval *tv, ns_j - if (!_job) { - return NS_ALLOCATION_FAILURE; - } -- pthread_mutex_lock(_job->monitor); -+ pthread_mutex_lock(&(_job->monitor)); - _job->tv = *tv; - - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_add_io_timeout_job state %d moving to NS_JOB_ARMED\n", (_job)->state); - #endif - _job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(_job->monitor); -+ pthread_mutex_unlock(&(_job->monitor)); - internal_ns_job_rearm(_job); - - /* fill in a pointer to the job for the caller if requested */ -@@ -982,12 +993,12 @@ ns_add_signal_job(ns_thrpool_t *tp, int32_t signum, ns_job_type_t job_type, ns_j - return NS_ALLOCATION_FAILURE; - } - -- pthread_mutex_lock(_job->monitor); -+ pthread_mutex_lock(&(_job->monitor)); - #ifdef DEBUG - ns_log(LOG_DEBUG, "ns_add_signal_job state %d moving to NS_JOB_ARMED\n", (_job)->state); - #endif - _job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(_job->monitor); -+ pthread_mutex_unlock(&(_job->monitor)); - internal_ns_job_rearm(_job); - - /* fill in a pointer to the job for the caller if requested */ -@@ -1038,9 +1049,9 @@ ns_add_shutdown_job(ns_thrpool_t *tp) - if (!_job) { - return NS_ALLOCATION_FAILURE; - } -- pthread_mutex_lock(_job->monitor); -+ pthread_mutex_lock(&(_job->monitor)); - _job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(_job->monitor); -+ pthread_mutex_unlock(&(_job->monitor)); - internal_ns_job_rearm(_job); - return NS_SUCCESS; - } -@@ -1061,13 +1072,13 @@ void * - ns_job_get_data(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state != NS_JOB_DELETED); - if (job->state != NS_JOB_DELETED) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return job->data; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NULL; - } - } -@@ -1076,14 +1087,14 @@ ns_result_t - ns_job_set_data(ns_job_t *job, void *data) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING); - if (job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING) { - job->data = data; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_SUCCESS; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_INVALID_STATE; - } - } -@@ -1092,13 +1103,13 @@ ns_thrpool_t * - ns_job_get_tp(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state != NS_JOB_DELETED); - if (job->state != NS_JOB_DELETED) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return job->tp; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NULL; - } - } -@@ -1107,13 +1118,13 @@ ns_job_type_t - ns_job_get_output_type(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state == NS_JOB_RUNNING); - if (job->state == NS_JOB_RUNNING) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return job->output_job_type; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return 0; - } - } -@@ -1122,13 +1133,13 @@ ns_job_type_t - ns_job_get_type(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state != NS_JOB_DELETED); - if (job->state != NS_JOB_DELETED) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return job->job_type; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return 0; - } - } -@@ -1137,13 +1148,13 @@ PRFileDesc * - ns_job_get_fd(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state != NS_JOB_DELETED); - if (job->state != NS_JOB_DELETED) { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return job->fd; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NULL; - } - } -@@ -1152,18 +1163,40 @@ ns_result_t - ns_job_set_done_cb(struct ns_job_t *job, ns_job_func_t func) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING); - if (job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING) { - job->done_cb = func; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_SUCCESS; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_INVALID_STATE; - } - } - -+ns_result_t -+ns_job_wait(struct ns_job_t *job) { -+ PR_ASSERT(job); -+ pthread_mutex_lock(&(job->monitor)); -+ if (job->state == NS_JOB_WAITING) { -+ /* It's done */ -+ pthread_mutex_unlock(&(job->monitor)); -+ return NS_SUCCESS; -+ } else { -+ pthread_cond_wait(&(job->notify), &(job->monitor)); -+ ns_job_state_t result = job->state; -+ pthread_mutex_unlock(&(job->monitor)); -+ if (result == NS_JOB_WAITING) { -+ return NS_SUCCESS; -+ } else if (result == NS_JOB_NEEDS_DELETE) { -+ return NS_DELETING; -+ } else { -+ PR_ASSERT(1 == 0); -+ return NS_INVALID_STATE; -+ } -+ } -+} - - /* - * This is a convenience function - use if you need to re-arm the same event -@@ -1173,7 +1206,7 @@ ns_result_t - ns_job_rearm(ns_job_t *job) - { - PR_ASSERT(job); -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - PR_ASSERT(job->state == NS_JOB_WAITING || job->state == NS_JOB_RUNNING); - - if (ns_thrpool_is_shutdown(job->tp)) { -@@ -1186,7 +1219,7 @@ ns_job_rearm(ns_job_t *job) - #endif - job->state = NS_JOB_NEEDS_ARM; - internal_ns_job_rearm(job); -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_SUCCESS; - } else if (!NS_JOB_IS_PERSIST(job->job_type) && job->state == NS_JOB_RUNNING) { - /* For this to be called, and NS_JOB_RUNNING, we *must* be the callback thread! */ -@@ -1195,10 +1228,10 @@ ns_job_rearm(ns_job_t *job) - ns_log(LOG_DEBUG, "ns_rearm_job %x state %d setting NS_JOB_NEEDS_ARM\n", job, job->state); - #endif - job->state = NS_JOB_NEEDS_ARM; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_SUCCESS; - } else { -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - return NS_INVALID_STATE; - } - /* Unreachable code .... */ -@@ -1254,7 +1287,7 @@ setup_event_q_wakeup(ns_thrpool_t *tp) - NS_JOB_READ | NS_JOB_PERSIST | NS_JOB_PRESERVE_FD, - wakeup_cb, NULL); - -- pthread_mutex_lock(job->monitor); -+ pthread_mutex_lock(&(job->monitor)); - - /* The event_queue wakeup is ready, arm it. */ - #ifdef DEBUG -@@ -1267,7 +1300,7 @@ setup_event_q_wakeup(ns_thrpool_t *tp) - - /* Stash the wakeup job in tp so we can release it later. */ - tp->event_q_wakeup_job = job; -- pthread_mutex_unlock(job->monitor); -+ pthread_mutex_unlock(&(job->monitor)); - } - - /* Initialize the thrpool config */ -@@ -1463,7 +1496,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp) - * and use it to wake up the event loop. - */ - -- pthread_mutex_lock(tp->event_q_wakeup_job->monitor); -+ pthread_mutex_lock(&(tp->event_q_wakeup_job->monitor)); - - // tp->event_q_wakeup_job->job_type |= NS_JOB_THREAD; - /* This triggers the job to "run", which will cause a shutdown cascade */ -@@ -1471,7 +1504,7 @@ ns_thrpool_destroy(struct ns_thrpool_t *tp) - ns_log(LOG_DEBUG, "ns_thrpool_destroy %x state %d moving to NS_JOB_NEEDS_DELETE\n", tp->event_q_wakeup_job, tp->event_q_wakeup_job->state); - #endif - tp->event_q_wakeup_job->state = NS_JOB_NEEDS_DELETE; -- pthread_mutex_unlock(tp->event_q_wakeup_job->monitor); -+ pthread_mutex_unlock(&(tp->event_q_wakeup_job->monitor)); - /* Has to be event_q_notify, not internal_job_done */ - event_q_notify(tp->event_q_wakeup_job); - -diff --git a/src/nunc-stans/test/test_nuncstans.c b/src/nunc-stans/test/test_nuncstans.c -index 629377a89..afe3c02fc 100644 ---- a/src/nunc-stans/test/test_nuncstans.c -+++ b/src/nunc-stans/test/test_nuncstans.c -@@ -55,14 +55,21 @@ - /* We need the internal headers for state checks */ - #include "../ns/ns_event_fw.h" - -+#include -+ -+#include -+ - #ifdef HAVE_STDLIB_H - #include - #endif - - - static int cb_check = 0; --static PRLock *cb_lock = NULL; --static PRCondVar *cb_cond = NULL; -+ -+static pthread_mutex_t cb_lock; -+static pthread_cond_t cb_cond; -+// static PRLock *cb_lock = NULL; -+// static PRCondVar *cb_cond = NULL; - - void - ns_test_logger(int priority __attribute__((unused)), const char *fmt, va_list varg) -@@ -71,6 +78,19 @@ ns_test_logger(int priority __attribute__((unused)), const char *fmt, va_list va - vprintf(fmt, varg); - } - -+static int -+cond_wait_rel(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict reltime) { -+ struct timespec now; -+ struct timespec abswait; -+ -+ clock_gettime(CLOCK_REALTIME, &now); -+ -+ abswait.tv_sec = now.tv_sec + reltime->tv_sec; -+ abswait.tv_nsec = now.tv_nsec + reltime->tv_nsec; -+ -+ return pthread_cond_timedwait(cond, mutex, &abswait); -+} -+ - /* All our other tests will use this in some form. */ - static int - ns_test_setup(void **state) -@@ -81,8 +101,8 @@ ns_test_setup(void **state) - /* Reset the callback check */ - cb_check = 0; - /* Create the cond var the CB check will use. */ -- cb_lock = PR_NewLock(); -- cb_cond = PR_NewCondVar(cb_lock); -+ assert(pthread_mutex_init(&cb_lock, NULL) == 0); -+ assert(pthread_cond_init(&cb_cond, NULL) == 0); - - ns_thrpool_config_init(&ns_config); - -@@ -105,8 +125,8 @@ ns_test_teardown(void **state) - - ns_thrpool_destroy(tp); - -- PR_DestroyCondVar(cb_cond); -- PR_DestroyLock(cb_lock); -+ pthread_cond_destroy(&cb_cond); -+ pthread_mutex_destroy(&cb_lock); - - return 0; - } -@@ -114,24 +134,23 @@ ns_test_teardown(void **state) - static void - ns_init_test_job_cb(struct ns_job_t *job __attribute__((unused))) - { -+ pthread_mutex_lock(&cb_lock); - cb_check += 1; -- PR_Lock(cb_lock); -- PR_NotifyCondVar(cb_cond); -- PR_Unlock(cb_lock); -+ pthread_cond_signal(&cb_cond); -+ pthread_mutex_unlock(&cb_lock); - } - - static void - ns_init_disarm_job_cb(struct ns_job_t *job) - { - if (ns_job_done(job) == NS_SUCCESS) { -+ pthread_mutex_lock(&cb_lock); - cb_check = 1; -+ pthread_cond_signal(&cb_cond); -+ pthread_mutex_unlock(&cb_lock); - } else { - assert_int_equal(1, 0); - } -- PR_Lock(cb_lock); -- PR_NotifyCondVar(cb_cond); -- /* Disarm ourselves */ -- PR_Unlock(cb_lock); - } - - static void -@@ -146,20 +165,20 @@ ns_init_test(void **state) - { - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {1, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_test_job_cb, NULL, &job), - 0); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - assert_int_equal(cb_check, 1); - - /* Once the job is done, it's not in the event queue, and it's complete */ -- /* We have to stall momentarily to let the work_job_execute release the job to us */ -- PR_Sleep(PR_SecondsToInterval(1)); -+ assert(ns_job_wait(job) == NS_SUCCESS); - assert_int_equal(ns_job_done(job), NS_SUCCESS); - } - -@@ -169,19 +188,20 @@ ns_set_data_test(void **state) - /* Add a job with data */ - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {1, 0}; - - char *data = malloc(6); - - strcpy(data, "first"); - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_test_job_cb, data, &job), - NS_SUCCESS); - - /* Let the job run */ -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - /* Check that the data is correct */ - char *retrieved = (char *)ns_job_get_data(job); -@@ -193,16 +213,14 @@ ns_set_data_test(void **state) - data = malloc(7); - strcpy(data, "second"); - -- while (job->state != NS_JOB_WAITING) { -- PR_Sleep(PR_MillisecondsToInterval(50)); -- } -+ assert(ns_job_wait(job) == NS_SUCCESS); - ns_job_set_data(job, data); - - /* Rearm, and let it run again. */ -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - ns_job_rearm(job); -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - /* Make sure it's now what we expect */ - retrieved = (char *)ns_job_get_data(job); -@@ -218,9 +236,7 @@ ns_set_data_test(void **state) - * waiting. we might need a load barrier here ... - */ - -- while (job->state != NS_JOB_WAITING) { -- PR_Sleep(PR_MillisecondsToInterval(50)); -- } -+ assert(ns_job_wait(job) == NS_SUCCESS); - - assert_int_equal(ns_job_done(job), NS_SUCCESS); - } -@@ -230,8 +246,9 @@ ns_job_done_cb_test(void **state) - { - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {1, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_create_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_do_nothing_cb, &job), - NS_SUCCESS); -@@ -240,8 +257,8 @@ ns_job_done_cb_test(void **state) - /* Remove it */ - assert_int_equal(ns_job_done(job), NS_SUCCESS); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - assert_int_equal(cb_check, 1); - } -@@ -250,16 +267,15 @@ static void - ns_init_rearm_job_cb(struct ns_job_t *job) - { - if (ns_job_rearm(job) != NS_SUCCESS) { -+ pthread_mutex_lock(&cb_lock); - cb_check = 1; - /* we failed to re-arm as expected, let's go away ... */ - assert_int_equal(ns_job_done(job), NS_SUCCESS); -+ pthread_cond_signal(&cb_cond); -+ pthread_mutex_unlock(&cb_lock); - } else { - assert_int_equal(1, 0); - } -- PR_Lock(cb_lock); -- PR_NotifyCondVar(cb_cond); -- /* Disarm ourselves */ -- PR_Unlock(cb_lock); - } - - static void -@@ -268,8 +284,9 @@ ns_job_persist_rearm_ignore_test(void **state) - /* Test that rearm ignores the persistent job. */ - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {1, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_create_job(tp, NS_JOB_NONE | NS_JOB_THREAD | NS_JOB_PERSIST, ns_init_rearm_job_cb, &job), - NS_SUCCESS); -@@ -281,8 +298,8 @@ ns_job_persist_rearm_ignore_test(void **state) - * should see only 1 in the cb_check. - */ - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - /* If we fail to rearm, this is set to 1 Which is what we want. */ - assert_int_equal(cb_check, 1); -@@ -294,6 +311,7 @@ ns_job_persist_disarm_test(void **state) - /* Make a persistent job */ - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {2, 0}; - - assert_int_equal( - ns_create_job(tp, NS_JOB_NONE | NS_JOB_PERSIST, ns_init_disarm_job_cb, &job), -@@ -302,9 +320,9 @@ ns_job_persist_disarm_test(void **state) - assert_int_equal(ns_job_rearm(job), NS_SUCCESS); - - /* In the callback it should disarm */ -- PR_Lock(cb_lock); -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ pthread_mutex_lock(&cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - /* Make sure it did */ - assert_int_equal(cb_check, 1); - } -@@ -329,14 +347,13 @@ ns_job_persist_disarm_test(void **state) - static void - ns_init_race_done_job_cb(struct ns_job_t *job) - { -- cb_check += 1; - ns_job_done(job); - /* We need to sleep to let the job race happen */ - PR_Sleep(PR_SecondsToInterval(2)); -- PR_Lock(cb_lock); -- PR_NotifyCondVar(cb_cond); -- /* Disarm ourselves */ -- PR_Unlock(cb_lock); -+ pthread_mutex_lock(&cb_lock); -+ cb_check += 1; -+ pthread_cond_signal(&cb_cond); -+ pthread_mutex_unlock(&cb_lock); - } - - static void -@@ -344,14 +361,15 @@ ns_job_race_done_test(void **state) - { - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {5, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_add_job(tp, NS_JOB_NONE | NS_JOB_THREAD, ns_init_race_done_job_cb, NULL, &job), - NS_SUCCESS); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(5)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - assert_int_equal(cb_check, 1); - } -@@ -365,8 +383,9 @@ ns_job_signal_cb_test(void **state) - { - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -+ struct timespec timeout = {1, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_int_equal( - ns_add_signal_job(tp, SIGUSR1, NS_JOB_SIGNAL, ns_init_test_job_cb, NULL, &job), - NS_SUCCESS); -@@ -376,8 +395,8 @@ ns_job_signal_cb_test(void **state) - /* Send the signal ... */ - raise(SIGUSR1); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -- PR_Unlock(cb_lock); -+ assert(cond_wait_rel(&cb_cond, &cb_lock, &timeout) == 0); -+ pthread_mutex_unlock(&cb_lock); - - assert_int_equal(cb_check, 1); - -@@ -408,12 +427,11 @@ ns_job_neg_timeout_test(void **state) - static void - ns_timer_job_cb(struct ns_job_t *job) - { -- cb_check += 1; - ns_job_done(job); -- PR_Lock(cb_lock); -- PR_NotifyCondVar(cb_cond); -- /* Disarm ourselves */ -- PR_Unlock(cb_lock); -+ pthread_mutex_lock(&cb_lock); -+ cb_check += 1; -+ pthread_cond_signal(&cb_cond); -+ pthread_mutex_unlock(&cb_lock); - } - - static void -@@ -421,16 +439,19 @@ ns_job_timer_test(void **state) - { - struct ns_thrpool_t *tp = *state; - struct ns_job_t *job = NULL; -- struct timeval tv = {2, 0}; -+ struct timeval tv = {3, 0}; -+ struct timespec timeout = {2, 0}; - -- PR_Lock(cb_lock); -+ pthread_mutex_lock(&cb_lock); - assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_job_cb, NULL, &job) == NS_SUCCESS); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(1)); -+ cond_wait_rel(&cb_cond, &cb_lock, &timeout); -+ // pthread_mutex_unlock(&cb_lock); - assert_int_equal(cb_check, 0); - -- PR_WaitCondVar(cb_cond, PR_SecondsToInterval(2)); -- PR_Unlock(cb_lock); -+ // pthread_mutex_lock(&cb_lock); -+ cond_wait_rel(&cb_cond, &cb_lock, &timeout); -+ pthread_mutex_unlock(&cb_lock); - assert_int_equal(cb_check, 1); - } - -@@ -441,7 +462,9 @@ ns_job_timer_test(void **state) - static void - ns_timer_persist_job_cb(struct ns_job_t *job) - { -+ pthread_mutex_lock(&cb_lock); - cb_check += 1; -+ pthread_mutex_unlock(&cb_lock); - if (cb_check < 10) { - ns_job_rearm(job); - } else { -@@ -456,16 +479,19 @@ ns_job_timer_persist_test(void **state) - struct ns_job_t *job = NULL; - struct timeval tv = {1, 0}; - -- PR_Lock(cb_lock); - assert_true(ns_add_timeout_job(tp, &tv, NS_JOB_THREAD, ns_timer_persist_job_cb, NULL, &job) == NS_SUCCESS); - - PR_Sleep(PR_SecondsToInterval(5)); - -+ pthread_mutex_lock(&cb_lock); - assert_true(cb_check <= 6); -+ pthread_mutex_unlock(&cb_lock); - - PR_Sleep(PR_SecondsToInterval(6)); - -+ pthread_mutex_lock(&cb_lock); - assert_int_equal(cb_check, 10); -+ pthread_mutex_unlock(&cb_lock); - } - - int --- -2.13.6 - diff --git a/SOURCES/0031-Ticket-49230-slapi_register_plugin-creates-config-en.patch b/SOURCES/0031-Ticket-49230-slapi_register_plugin-creates-config-en.patch new file mode 100644 index 0000000..f8e5141 --- /dev/null +++ b/SOURCES/0031-Ticket-49230-slapi_register_plugin-creates-config-en.patch @@ -0,0 +1,50 @@ +From 91a162d66c2fe239c009f1ee16974d310b333e7e Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0031-Ticket-49410-opened-connection-can-remain-no-longer-.patch b/SOURCES/0031-Ticket-49410-opened-connection-can-remain-no-longer-.patch deleted file mode 100644 index b62e8b8..0000000 --- a/SOURCES/0031-Ticket-49410-opened-connection-can-remain-no-longer-.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 11cea14acfc11d0328013b61a3e1396e97dfe577 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 14 Nov 2017 16:29:03 +0100 -Subject: [PATCH] Ticket 49410 - opened connection can remain no longer poll, - like hanging - -Bug Description: - Some opened connection are no longer poll. - Those connections has 'gettingber' toggle set although there is - no more worker thread reading it. - The reason they have gettingber set is that the last - operation had 'persistent search' flag. With such flag - gettingber is not reset. - persistent flag is set even when no persistent search/sync_repl - was received on the connection. - The problem is that the flag is tested on the wrong operation. - The tested operation can be - - the first operation when the connection entered in turbo mode - - the previous operation if several ops PDUs were read on the network - - accessing random memory - - In theory testing the flag can lead to sigsev even - if it never crash - -Fix Description: - The fix is to use the operation that is in the pblock - In such case pb_op is no longer used, so we can get rid of it. - In addition make pb_conn a local variable where it is used - -https://pagure.io/389-ds-base/issue/49410 - -Reviewed by: Ludwig Krispenz, Mark Reynolds - -Platforms tested: F26 - -Flag Day: no - -Doc impact: no ---- - ldap/servers/slapd/connection.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c -index 24a7a1c05..3f19b9765 100644 ---- a/ldap/servers/slapd/connection.c -+++ b/ldap/servers/slapd/connection.c -@@ -1498,8 +1498,6 @@ connection_threadmain() - int maxthreads = 0; - int enable_nunc_stans = 0; - long bypasspollcnt = 0; -- Connection *pb_conn = NULL; -- Operation *pb_op = NULL; - - enable_nunc_stans = config_get_enable_nunc_stans(); - #if defined(hpux) -@@ -1520,6 +1518,8 @@ connection_threadmain() - } - - if (!thread_turbo_flag && !more_data) { -+ Connection *pb_conn = NULL; -+ - /* If more data is left from the previous connection_read_operation, - we should finish the op now. Client might be thinking it's - done sending the request and wait for the response forever. -@@ -1530,7 +1530,6 @@ connection_threadmain() - * Connection wait for new work provides the conn and op for us. - */ - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - - switch (ret) { - case CONN_NOWORK: -@@ -1786,7 +1785,7 @@ connection_threadmain() - /* total number of ops for the server */ - slapi_counter_increment(ops_completed); - /* If this op isn't a persistent search, remove it */ -- if (pb_op->o_flags & OP_FLAG_PS) { -+ if (op->o_flags & OP_FLAG_PS) { - PR_EnterMonitor(conn->c_mutex); - connection_release_nolock(conn); /* psearch acquires ref to conn - release this one now */ - PR_ExitMonitor(conn->c_mutex); --- -2.13.6 - diff --git a/SOURCES/0032-49227-ldapsearch-for-nsslapd-errorlog-level-re.patch b/SOURCES/0032-49227-ldapsearch-for-nsslapd-errorlog-level-re.patch new file mode 100644 index 0000000..d2fd071 --- /dev/null +++ b/SOURCES/0032-49227-ldapsearch-for-nsslapd-errorlog-level-re.patch @@ -0,0 +1,221 @@ +From e5f78f9f6a8cab7bfbd33e14912508183f9da283 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0032-Ticket-49443-scope-one-searches-in-1.3.7-give-incorr.patch b/SOURCES/0032-Ticket-49443-scope-one-searches-in-1.3.7-give-incorr.patch deleted file mode 100644 index b90b8b2..0000000 --- a/SOURCES/0032-Ticket-49443-scope-one-searches-in-1.3.7-give-incorr.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5f38be985bc98969b0fdaa6ece8f84b11bdddc2f Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Thu, 9 Nov 2017 10:20:44 +0100 -Subject: [PATCH] Ticket 49443 - scope one searches in 1.3.7 give incorrect - results - -Bug: if a onelevel search is done for an unidexed attribute, the filter test is skipped - and all children of the search base are returned - -Fix: enforce filter test if allids - -Reviewed by: Mark, thanks ---- - ldap/servers/slapd/back-ldbm/idl_set.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c -index ba39ff03f..b68e7ab76 100644 ---- a/ldap/servers/slapd/back-ldbm/idl_set.c -+++ b/ldap/servers/slapd/back-ldbm/idl_set.c -@@ -349,6 +349,11 @@ idl_set_intersect(IDListSet *idl_set, backend *be) - { - IDList *result_list = NULL; - -+ if (idl_set->allids) { -+ /* if any component was allids we have to apply the filtertest */ -+ slapi_be_set_flag(be, SLAPI_BE_FLAG_DONT_BYPASS_FILTERTEST); -+ } -+ - if (idl_set->allids != 0 && idl_set->count == 0) { - /* - * We only have allids, so must be allids. --- -2.13.6 - diff --git a/SOURCES/0033-Ticket-48989-fix-perf-counters.patch b/SOURCES/0033-Ticket-48989-fix-perf-counters.patch new file mode 100644 index 0000000..fd75c88 --- /dev/null +++ b/SOURCES/0033-Ticket-48989-fix-perf-counters.patch @@ -0,0 +1,57 @@ +From a7b9a9ddbff47c2226e60e403374d5e451fac344 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0033-Ticket-49441-Import-crashes-with-large-indexed-binar.patch b/SOURCES/0033-Ticket-49441-Import-crashes-with-large-indexed-binar.patch deleted file mode 100644 index d304225..0000000 --- a/SOURCES/0033-Ticket-49441-Import-crashes-with-large-indexed-binar.patch +++ /dev/null @@ -1,1048 +0,0 @@ -From 737a34433df469e0e2de9e70e3960eb253448109 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 6 Nov 2017 21:58:52 -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!) - -(cherry picked from commit b4497c4f28501b188797e12909983853642af967) ---- - dirsrvtests/tests/data/ticket49441/binary.ldif | 858 +++++++++++++++++++++++++ - dirsrvtests/tests/tickets/ticket49441_test.py | 74 +++ - ldap/servers/slapd/back-ldbm/index.c | 21 +- - 3 files changed, 943 insertions(+), 10 deletions(-) - create mode 100644 dirsrvtests/tests/data/ticket49441/binary.ldif - create mode 100644 dirsrvtests/tests/tickets/ticket49441_test.py - -diff --git a/dirsrvtests/tests/data/ticket49441/binary.ldif b/dirsrvtests/tests/data/ticket49441/binary.ldif -new file mode 100644 -index 000000000..bdebaf817 ---- /dev/null -+++ b/dirsrvtests/tests/data/ticket49441/binary.ldif -@@ -0,0 +1,858 @@ -+version: 1 -+ -+# entry-id: 1 -+dn: dc=example,dc=com -+objectClass: domain -+objectClass: top -+dc: example -+nsUniqueId: f49ca102-c2ee11e7-9170b029-e68fda34 -+creatorsName: -+modifiersName: -+createTimestamp: 20171106123544Z -+modifyTimestamp: 20171106123544Z -+ -+# entry-id: 2 -+dn: ou=binary,dc=example,dc=com -+certificateRevocationList;binary:: MIITbjCCElYCAQEwDQYJKoZIhvcNAQEFBQAwVzELMAk -+ GA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9y -+ aXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQRcNMTcxMDE2MTUxNjAyWhcNMTcxMDE5MTUxNjAyWjCCE -+ ZcwIwIEV4cj0hcNMTYxMTMwMDAyNDA0WjAMMAoGA1UdFQQDCgEAMCMCBFeHI9EXDTE2MTEzMDAwMj -+ gwNVowDDAKBgNVHRUEAwoBADAjAgRXhyPPFw0xNjExMzAwMDIxNDJaMAwwCgYDVR0VBAMKAQAwIwI -+ EV4cjzhcNMTYxMTMwMDAzMTE0WjAMMAoGA1UdFQQDCgEAMCMCBFeHI2gXDTE2MTEyOTE1MTM0M1ow -+ DDAKBgNVHRUEAwoBADA9AgRXhwCzFw0xNjExMDIyMjQ0NThaMCYwCgYDVR0VBAMKAQEwGAYDVR0YB -+ BEYDzIwMTYwOTA3MDEzODU1WjAjAgRXhvE4Fw0xNjA4MDExNDA5MTFaMAwwCgYDVR0VBAMKAQAwIw -+ IEV4bxNxcNMTYwODAxMTQwODU4WjAMMAoGA1UdFQQDCgEAMCMCBEkD2YYXDTE2MDcwNTE1NTg0NVo -+ wDDAKBgNVHRUEAwoBADAjAgRJA9mFFw0xNjA3MDUxNTU1MTlaMAwwCgYDVR0VBAMKAQAwIwIESQPT -+ cRcNMTYxMTMwMDAyODA1WjAMMAoGA1UdFQQDCgEAMCMCBEkD03AXDTE2MTEzMDAwMjgwNVowDDAKB -+ gNVHRUEAwoBADAjAgRJA9NuFw0xNjA2MjAxNjQ4NTlaMAwwCgYDVR0VBAMKAQAwIwIESQPSOBcNMT -+ YwNjE3MTU1OTM4WjAMMAoGA1UdFQQDCgEAMCMCBEkD0jcXDTE2MTEzMDAwMzExNFowDDAKBgNVHRU -+ EAwoBADAjAgRJA9I0Fw0xNjA2MjAxNzAyMDJaMAwwCgYDVR0VBAMKAQAwIwIESQPSMxcNMTYwNjIw -+ MTcwMjAyWjAMMAoGA1UdFQQDCgEAMCMCBEkD0jEXDTE2MDYxNzE1NDgwMlowDDAKBgNVHRUEAwoBA -+ DAjAgRJA9IwFw0xNjExMzAwMDMxMTRaMAwwCgYDVR0VBAMKAQAwIwIESQPSLhcNMTYwNjE3MTU0MD -+ A2WjAMMAoGA1UdFQQDCgEAMCMCBEkD0VIXDTE2MTEzMDAwMzExNFowDDAKBgNVHRUEAwoBADAjAgR -+ JA9FRFw0xNjExMzAwMDMxMTRaMAwwCgYDVR0VBAMKAQAwIwIESQPRTxcNMTYwNjE1MTkyMDU4WjAM -+ MAoGA1UdFQQDCgEAMCMCBEkD0U4XDTE2MDYxNTE5MjYyMlowDDAKBgNVHRUEAwoBADAjAgRJA9FLF -+ w0xNjA2MTUxODQ5MzZaMAwwCgYDVR0VBAMKAQAwIwIESQPRShcNMTYwNjE1MTQzNDU1WjAMMAoGA1 -+ UdFQQDCgEAMCMCBEkD0UkXDTE2MDYxNTE0MzEyMlowDDAKBgNVHRUEAwoBADAjAgRJA9FIFw0xNjA -+ 2MTUxNDMwMTdaMAwwCgYDVR0VBAMKAQAwIwIESQPQexcNMTYwNjE1MTkyNjIyWjAMMAoGA1UdFQQD -+ CgEAMCMCBEkD0HoXDTE2MDYxNTE5MjYyMlowDDAKBgNVHRUEAwoBADAjAgRJA9B4Fw0xNjA2MTQxM -+ TQ3MzlaMAwwCgYDVR0VBAMKAQAwIwIESQPQdxcNMTYwNjE1MTkyNTU5WjAMMAoGA1UdFQQDCgEAMC -+ MCBEkD0HYXDTE2MDYxNTE5MjU1OVowDDAKBgNVHRUEAwoBADAjAgRJA9B0Fw0xNjA2MTQxMTQzMzh -+ aMAwwCgYDVR0VBAMKAQAwIwIESQPQcxcNMTYwNjE0MTE0MDU4WjAMMAoGA1UdFQQDCgEAMCMCBEkD -+ 0HIXDTE2MDYxNTE5MjU0NlowDDAKBgNVHRUEAwoBADAjAgRJA9BwFw0xNjA2MTQxMTE3NDlaMAwwC -+ gYDVR0VBAMKAQAwIwIESQPLhhcNMTYwNjAxMjI1NTA1WjAMMAoGA1UdFQQDCgEAMCMCBEkDyRgXDT -+ E2MDUyNjIxNDQwOFowDDAKBgNVHRUEAwoBADAjAgRJA8kXFw0xNjA1MjYyMTQzMjdaMAwwCgYDVR0 -+ VBAMKAQAwIwIESQPIsRcNMTYwNTI2MTUxOTMwWjAMMAoGA1UdFQQDCgEAMCMCBEkDmmEXDTE2MDYx -+ NTE5MjU0NlowDDAKBgNVHRUEAwoBADAjAgRJA5pgFw0xNjA2MTUxOTI1NDZaMAwwCgYDVR0VBAMKA -+ QAwIwIESQOZ9RcNMTYwNjE1MTkyNDQzWjAMMAoGA1UdFQQDCgEFMCMCBEkDmfQXDTE2MDYxNTE5Mj -+ Q0M1owDDAKBgNVHRUEAwoBBTAjAgRJA5nyFw0xNjAyMDExOTM0MTlaMAwwCgYDVR0VBAMKAQAwIwI -+ ESQOXgBcNMTYwMTI2MTUwNTE5WjAMMAoGA1UdFQQDCgEAMCMCBEkDh0oXDTE1MTIxNzE3MzE0NVow -+ DDAKBgNVHRUEAwoBAzAjAgRJA3ZBFw0xNjAyMDIxNDM3MTZaMAwwCgYDVR0VBAMKAQMwIwIESQN2Q -+ BcNMTYwMjAyMTQzNzAzWjAMMAoGA1UdFQQDCgEDMCMCBEkDXsUXDTE1MTIwODIwMTM0OVowDDAKBg -+ NVHRUEAwoBAzAjAgRJA17EFw0xNTEyMDgyMDEzNDlaMAwwCgYDVR0VBAMKAQMwIwIESQNewxcNMTU -+ xMjA4MjAxMzUwWjAMMAoGA1UdFQQDCgEDMCMCBEkDWrkXDTE1MTIwODIwMTM1MFowDDAKBgNVHRUE -+ AwoBAzAjAgRJA1q4Fw0xNTEyMDgyMDEzNTBaMAwwCgYDVR0VBAMKAQMwIwIESQNatxcNMTUxMjA4M -+ jAxMzUwWjAMMAoGA1UdFQQDCgEDMCMCBEkDNjMXDTE2MDcwNTIwMDcxMlowDDAKBgNVHRUEAwoBBT -+ AjAgRJAwpwFw0xNjA2MTUxOTQwMDNaMAwwCgYDVR0VBAMKAQAwIwIESQMKbxcNMTYwNjE1MTk0MDA -+ zWjAMMAoGA1UdFQQDCgEAMCMCBEkC2Z0XDTE0MTAyMDE2NDgzN1owDDAKBgNVHRUEAwoBBTAjAgRJ -+ AthhFw0xNDEwMjAxNjQ4MzdaMAwwCgYDVR0VBAMKAQUwIwIESQLX7RcNMTQxMTEyMjAyNjA1WjAMM -+ AoGA1UdFQQDCgEFMCMCBEkC1+sXDTE0MTAyNzE1NTI1OVowDDAKBgNVHRUEAwoBAzAjAgRJAn2hFw -+ 0xNDAzMTMxNjUwMjZaMAwwCgYDVR0VBAMKAQAwIwIESQJ9MxcNMTQwMzEyMTUxODI5WjAMMAoGA1U -+ dFQQDCgEAMCMCBEkCfTEXDTE0MDMxMjExMzMzNVowDDAKBgNVHRUEAwoBADAjAgRJAn0wFw0xNDAz -+ MTIxMjE4MjFaMAwwCgYDVR0VBAMKAQAwIwIESQJ8YxcNMTQwMzEyMTEyNzEwWjAMMAoGA1UdFQQDC -+ gEAMCMCBEkCfGEXDTE0MDMxMDE0NTYxNlowDDAKBgNVHRUEAwoBADAjAgRJAnxgFw0xNDAzMTAxNT -+ A4MTVaMAwwCgYDVR0VBAMKAQAwIwIESQJ8XhcNMTQwMzEwMTIzMDM3WjAMMAoGA1UdFQQDCgEAMCM -+ CBEkCfF0XDTE0MDMxMDE0NTMyMlowDDAKBgNVHRUEAwoBADAjAgRJAnxbFw0xNDAzMTAxMDQ5NDBa -+ MAwwCgYDVR0VBAMKAQAwIwIESQJ8WhcNMTQwMzEwMTIwOTM2WjAMMAoGA1UdFQQDCgEAMCMCBEkCe -+ ywXDTE0MDMwNzEwMzcxM1owDDAKBgNVHRUEAwoBADAjAgRJAnsrFw0xNDAzMTAxMDQ3MTdaMAwwCg -+ YDVR0VBAMKAQAwIwIESQJ6xRcNMTQwMzA2MTEwMDM3WjAMMAoGA1UdFQQDCgEAMCMCBEkCesQXDTE -+ 0MDMwNzEwMzMyNVowDDAKBgNVHRUEAwoBADAjAgRJAm7jFw0xNDAyMDQyMTMwMjFaMAwwCgYDVR0V -+ BAMKAQAwIwIESQJrWhcNMTQwMTI3MTIyMTI0WjAMMAoGA1UdFQQDCgEAMCMCBEkCa1kXDTE0MDMwN -+ jEwNTY0OFowDDAKBgNVHRUEAwoBADAjAgRJAmjyFw0xNDAxMjExMDEyMTlaMAwwCgYDVR0VBAMKAQ -+ AwIwIESQJiPRcNMTQwMTAyMTYwMjIxWjAMMAoGA1UdFQQDCgEAMCMCBEkCXFgXDTEzMTIxODE3NTI -+ wNVowDDAKBgNVHRUEAwoBADAjAgRJAlW1Fw0xMzEyMDIxNTAzNTVaMAwwCgYDVR0VBAMKAQAwIwIE -+ SQJVshcNMTMxMjAyMTQ1NTM2WjAMMAoGA1UdFQQDCgEAMCMCBEkCVbEXDTEzMTIwMjE0NTk1OVowD -+ DAKBgNVHRUEAwoBADAjAgRJAlWvFw0xMzEyMDIxNDE3MzBaMAwwCgYDVR0VBAMKAQAwIwIESQJVrh -+ cNMTMxMjAyMTQ0OTMxWjAMMAoGA1UdFQQDCgEAMCMCBEkCVawXDTEzMTIwMjEzMTA1OFowDDAKBgN -+ VHRUEAwoBADAjAgRJAlWrFw0xMzEyMDIxNDEyMTVaMAwwCgYDVR0VBAMKAQAwIwIESQJONRcNMTMx -+ MTEyMjExMzI0WjAMMAoGA1UdFQQDCgEAMCMCBEkCJrkXDTEzMDkxMDA2NDUyNFowDDAKBgNVHRUEA -+ woBADAjAgRJAhmPFw0xMzA4MjExMDM0MTFaMAwwCgYDVR0VBAMKAQAwIwIESQIVrBcNMTMwODEyMT -+ g1NTU1WjAMMAoGA1UdFQQDCgEAMCMCBEkCFasXDTEzMTIxODE3MDQ0MlowDDAKBgNVHRUEAwoBADA -+ jAgRJAhAoFw0xMzA3MjkxNjAwMzVaMAwwCgYDVR0VBAMKAQAwIwIESQIQJxcNMTQwMTAyMTU1MDUy -+ WjAMMAoGA1UdFQQDCgEAMCMCBEkCCh8XDTEzMDcxNTA3MzY1NlowDDAKBgNVHRUEAwoBADAjAgRJA -+ gexFw0xMzA3MDgxNTU5MTRaMAwwCgYDVR0VBAMKAQAwIwIESQH73BcNMTMwNzI5MTU1NTAzWjAMMA -+ oGA1UdFQQDCgEAMCMCBEkB5EcXDTEzMDUyOTE0MDUyNVowDDAKBgNVHRUEAwoBADAjAgRJAcDtFw0 -+ xMzA1MTAyMDExNTBaMAwwCgYDVR0VBAMKAQAwIwIESQGmXBcNMTMwNDEwMDkyMTI2WjAMMAoGA1Ud -+ FQQDCgEAMCMCBEkBnj0XDTEzMDMyNTE4MTc0MFowDDAKBgNVHRUEAwoBADAjAgRJAYMOFw0xMzAyM -+ TExMTEwNDdaMAwwCgYDVR0VBAMKAQAwIwIESQF4PRcNMTMwODEyMTg0ODE2WjAMMAoGA1UdFQQDCg -+ EAMCMCBEkBcwcXDTEzMDEwMzE2NTgyMFowDDAKBgNVHRUEAwoBADAjAgRJAXMEFw0xMzAxMDMxMDA -+ yMjRaMAwwCgYDVR0VBAMKAQAwIwIESQFuRxcNMTMxMDA3MTMwMjM1WjAMMAoGA1UdFQQDCgEFMCMC -+ BEkBaLsXDTEzMDQxMDA5MTY1NVowDDAKBgNVHRUEAwoBADAjAgRJAWaQFw0xMjExMjkxNjAxMzJaM -+ AwwCgYDVR0VBAMKAQAwIwIESQFmhBcNMTIxMTI5MTE1NTIyWjAMMAoGA1UdFQQDCgEAMCMCBEkBZo -+ MXDTEyMTEyOTE1MjYwNVowDDAKBgNVHRUEAwoBADAjAgRJAWaBFw0xMjExMjkxMTAzNTJaMAwwCgY -+ DVR0VBAMKAQAwIwIESQFmgBcNMTIxMTI5MTE1MTU4WjAMMAoGA1UdFQQDCgEAMCMCBEkBYT8XDTEy -+ MTExNTA5NTI1OVowDDAKBgNVHRUEAwoBADAjAgRJAWCrFw0xMjExMTQxNDM2NDVaMAwwCgYDVR0VB -+ AMKAQAwIwIESQFgqhcNMTIxMTE1MDk0ODI1WjAMMAoGA1UdFQQDCgEAMCMCBEkBXT4XDTEzMTIwMj -+ EzMDcwMVowDDAKBgNVHRUEAwoBADAjAgRJAVvbFw0xMjExMjkxMTAwMzFaMAwwCgYDVR0VBAMKAQC -+ gMDAuMAsGA1UdFAQEAgIo8DAfBgNVHSMEGDAWgBT0Fi4Bu6uQGaQoQg2dwB+crxCGKzANBgkqhkiG -+ 9w0BAQUFAAOCAQEATe14zpsSjrGcW4yNZrdGtsupuJge+DQV+h1ZwBEQtsmOmMvbSdMsu+vMvTzHQ -+ KWJq56picjixY6v4vPqhRRZWP8evOc0NuoxpiUhgez3CKFQoJ2bdeaS/WCfqss3Sa4FZTUzkVWZde -+ moDH8CcHt5in3H7SwF5i9/rKB/bLuTjQg+LRKh2E9+FAkJn1S/ZRh1Vjd/KuRFOXD6odjV54oTWE0 -+ 6PcHBdwip62ridLdQopt3+e1UgwKBNJAmBD6uMN1tPmenUYWxh4xI7Ft4HQR58TdIiTZmfQHmEkjl -+ dBNEAoUK1hvRy6E2mSdRq9Yex8f+rGdxI1+++6lHaN1+M8jQ4g== -+userCertificate;binary:: MIKE/jCCg+YCAQEwX6FdMFukWTBXMQswCQYDVQQGEwJVUzEQMA4GA -+ 1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECx -+ MJRENvbVN1YkNBMGegZTBjMFukWTBXMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCA -+ GA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBAgRIwMPg -+ MA0GCSqGSIb3DQEBBQUAAgRXh6kjMCIYDzIwMTcxMDE1MjI0NjEzWhgPMjAxNzExMTQyMjQ2MTNaM -+ IKCuTCCEQoGCSqGSIb2fQdEADGCEPswghD3gAEEMIIQ8DBvMFcxCzAJBgNVBAYTAlVTMRAwDgYDVQ -+ QKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwl -+ EQ29tU3ViQ0EWFENBIERvbWFpbiBTZWFyY2hiYXNlME4wPzEVMBMGCgmSJomT8ixkARkWBWxvY2Fs -+ MRQwEgYKCZImiZPyLGQBGRYEVGVzdDEQMA4GA1UECxMHRGV2aWNlcxYLQ0xTIERldmljZXMwgYswa -+ DEVMBMGCgmSJomT8ixkARkWBWxvY2FsMRQwEgYKCZImiZPyLGQBGRYEVGVzdDETMBEGA1UECxMKVG -+ VzdCBVc2VyczEkMCIGA1UECxMbU1NPIEFkbWluaXN0cmF0aW9uIEFjY291bnRzFh9DTFMgU1NPIEF -+ kbWluaXN0cmF0aW9uIEFjY291bnRzMFQwQjEVMBMGCgmSJomT8ixkARkWBWxvY2FsMRQwEgYKCZIm -+ iZPyLGQBGRYEVGVzdDETMBEGA1UECxMKVGVzdCBVc2VycxYOQ0xTIFRlc3QgVXNlcnMwfDBfMRUwE -+ wYKCZImiZPyLGQBGRYFbG9jYWwxFDASBgoJkiaJk/IsZAEZFgRUZXN0MRswGQYDVQQLExJEb21haW -+ 4gQ29udHJvbGxlcnMxEzARBgNVBAsTCkdCIFNlcnZlcnMWGUNMUyBHQiBEb21haW4gQ29udHJvbGx -+ lcnMwfDBfMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFDASBgoJkiaJk/IsZAEZFgR0ZXN0MRswGQYD -+ VQQLExJEb21haW4gQ29udHJvbGxlcnMxEzARBgNVBAsTClVTIFNlcnZlcnMWGUNMUyBVUyBEb21ha -+ W4gQ29udHJvbGxlcnMwgaIwgY4xFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEUMBIGCgmSJomT8ixkAR -+ kWBFRlc3QxFDASBgNVBAsTC1Rlc3QtT2ZmaWNlMRAwDgYDVQQLEwdTZXJ2ZXJzMRMwEQYDVQQLEwp -+ HQiBTZXJ2ZXJzMRQwEgYDVQQLEwtBcHBsaWNhdGlvbjEMMAoGA1UECxMDV0VCFg9DTFMgR0IgV2Vi -+ IEFwcHMwgbUwgaExFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEUMBIGCgmSJomT8ixkARkWBFRlc3QxF -+ DASBgNVBAsTC1Rlc3QtT2ZmaWNlMRAwDgYDVQQLEwdTZXJ2ZXJzMRMwEQYDVQQLEwpHQiBTZXJ2ZX -+ JzMRQwEgYDVQQLEwtBcHBsaWNhdGlvbjEMMAoGA1UECxMDV0VCMREwDwYDVQQLEwhJbnRyYW5ldBY -+ PQ0xTIEdCIEludHJhbmV0MIG1MIGhMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFDASBgoJkiaJk/Is -+ ZAEZFgRUZXN0MRQwEgYDVQQLEwtUZXN0LU9mZmljZTEQMA4GA1UECxMHU2VydmVyczETMBEGA1UEC -+ xMKVVMgU2VydmVyczEUMBIGA1UECxMLQXBwbGljYXRpb24xDDAKBgNVBAsTA1dFQjERMA8GA1UECx -+ MISW50cmFuZXQWD0NMUyBVUyBJbnRyYW5ldDA8MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnR -+ ydXN0MRAwDgYDVQQLEwdEeW5Db3JwFgdEeW5Db3JwMEowODELMAkGA1UEBhMCVVMxEDAOBgNVBAoT -+ B0VudHJ1c3QxFzAVBgNVBAsTDkFkbWluaXN0cmF0b3JzFg5BZG1pbmlzdHJhdG9yczBKMDgxCzAJB -+ gNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MRcwFQYDVQQLEw5HZW5lcmFsIE1vdG9ycxYOR2VuZX -+ JhbCBNb3RvcnMwczBZMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEXMBUGA1UECxMOR2V -+ uZXJhbCBNb3RvcnMxHzAdBgNVBAsTFkdNIFVzZXIgQWRtaW5pc3RyYXRvcnMWFkdNIFVzZXIgQWRt -+ aW5pc3RyYXRvcnMwXzBPMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEXMBUGA1UECxMOR -+ 2VuZXJhbCBNb3RvcnMxFTATBgNVBAsTDEdNIEVuZCBVc2VycxYMR00gRW5kIFVzZXJzMFYwQzEVMB -+ MGCgmSJomT8ixkARkWBWxvY2FsMRQwEgYKCZImiZPyLGQBGRYEVGVzdDEUMBIGA1UECxMLV2ViIFN -+ lcnZlcnMWD0NMUyBXZWIgU2VydmVyczBeMEcxFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEUMBIGCgmS -+ JomT8ixkARkWBFRlc3QxGDAWBgNVBAsTD0NNUyBBZG1pbiBVc2VycxYTQ0xTIENNUyBBZG1pbiBVc -+ 2VyczBeMEcxFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEUMBIGCgmSJomT8ixkARkWBFRlc3QxGDAWBg -+ NVBAsTD1BLSSBBZG1pbiBVc2VycxYTQ0xTIFBLSSBBZG1pbiBVc2VyczBLMD8xCzAJBgNVBAYTAnV -+ zMRAwDgYDVQQKEwdlbnRydXN0MQ8wDQYDVQQLEwZtb2JpbGUxDTALBgNVBAsTBGRlbW8WCERlbW8g -+ TURNMEgwMzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxEjAQBgNVBAsTCUVtcGxveWVlc -+ xYRRW50cnVzdCBFbXBsb3llZXMwWzBQMRUwEwYKCZImiZPyLGQBGRYFTG9jYWwxFDASBgoJkiaJk/ -+ IsZAEZFgRUZXN0MRMwEQYDVQQLEwpUZXN0IFVzZXJzMQwwCgYDVQQHEwNERVYWB0NMUyBERVYwJDA -+ cMQswCQYDVQQGEwJ1czENMAsGA1UEChMETklTVBYETklTVDB2MGcxCzAJBgNVBAYTAlVTMRAwDgYD -+ VQQKEwdFbnRydXN0MRkwFwYDVQQLExBNYW5hZ2VkIFNlcnZpY2VzMRkwFwYDVQQLExBEZW1vIENvb -+ VByaXYgU3ViMRAwDgYDVQQLEwdEZXZpY2VzFgtNU08gRGV2aWNlczCBhDBuMQswCQYDVQQGEwJVUz -+ EQMA4GA1UEChMHRW50cnVzdDEZMBcGA1UECxMQTWFuYWdlZCBTZXJ2aWNlczEZMBcGA1UECxMQRGV -+ tbyBDb21Qcml2IFN1YjEXMBUGA1UECxMOQWRtaW5pc3RyYXRvcnMWEk1TTyBBZG1pbmlzdHJhdG9y -+ czB6MGkxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MRkwFwYDVQQLExBNYW5hZ2VkIFNlc -+ nZpY2VzMRkwFwYDVQQLExBEZW1vIENvbVByaXYgU3ViMRIwEAYDVQQLEwlFbXBsb3llZXMWDU1TTy -+ BFbXBsb3llZXMwRDAxMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHR290U3ZlbjEQMA4GA1UECxMHRGV -+ 2aWNlcxYPR290U3ZlbiBEZXZpY2VzMIGEMFoxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0 -+ MSAwHgYDVQQLExdFbnRydXN0IFNhbGVzIEVuZ2luZWVyczEXMBUGA1UECxMOQWRtaW5pc3RyYXRvc -+ nMWJkVudHJ1c3QgU2FsZXMgRW5naW5lZXJzIEFkbWluaXN0cmF0b3JzMHYwUzELMAkGA1UEBhMCVV -+ MxEDAOBgNVBAoTB0VudHJ1c3QxIDAeBgNVBAsTF0VudHJ1c3QgU2FsZXMgRW5naW5lZXJzMRAwDgY -+ DVQQLEwdEZXZpY2VzFh9FbnRydXN0IFNhbGVzIEVuZ2luZWVycyBEZXZpY2VzMHIwUTELMAkGA1UE -+ BhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIDAeBgNVBAsTF0VudHJ1c3QgU2FsZXMgRW5naW5lZXJzM -+ Q4wDAYDVQQLEwVDYXJkcxYdRW50cnVzdCBTYWxlcyBFbmdpbmVlcnMgQ2FyZHMwdDBSMQswCQYDVQ -+ QGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEgMB4GA1UECxMXRW50cnVzdCBTYWxlcyBFbmdpbmVlcnM -+ xDzANBgNVBAsTBlBlb3BsZRYeRW50cnVzdCBTYWxlcyBFbmdpbmVlcnMgUGVvcGxlMIGKMF0xCzAJ -+ BgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSMwIQYDVQQLExpFbnRydXN0IFByb2R1Y3QgTWFuY -+ WdlbWVudDEXMBUGA1UECxMOQWRtaW5pc3RyYXRvcnMWKUVudHJ1c3QgUHJvZHVjdCBNYW5hZ2VtZW -+ 50IEFkbWluaXN0cmF0b3JzMHwwVjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIzAhBgN -+ VBAsTGkVudHJ1c3QgUHJvZHVjdCBNYW5hZ2VtZW50MRAwDgYDVQQLEwdEZXZpY2VzFiJFbnRydXN0 -+ IFByb2R1Y3QgTWFuYWdlbWVudCBEZXZpY2VzMHgwVDELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0Vud -+ HJ1c3QxIzAhBgNVBAsTGkVudHJ1c3QgUHJvZHVjdCBNYW5hZ2VtZW50MQ4wDAYDVQQLEwVDYXJkcx -+ YgRW50cnVzdCBQcm9kdWN0IE1hbmFnZW1lbnQgQ2FyZHMwejBVMQswCQYDVQQGEwJVUzEQMA4GA1U -+ EChMHRW50cnVzdDEjMCEGA1UECxMaRW50cnVzdCBQcm9kdWN0IE1hbmFnZW1lbnQxDzANBgNVBAsT -+ BlBlb3BsZRYhRW50cnVzdCBQcm9kdWN0IE1hbmFnZW1lbnQgUGVvcGxlMCQwHDELMAkGA1UEBhMCT -+ loxDTALBgNVBAoTBExJTloWBExJTlowTDA1MQswCQYDVQQGEwJOWjENMAsGA1UEChMETElOWjEXMB -+ UGA1UECxMOQWRtaW5pc3RyYXRvcnMWE0xJTlogQWRtaW5pc3RyYXRvcnMwPjAuMQswCQYDVQQGEwJ -+ OWjENMAsGA1UEChMETElOWjEQMA4GA1UECxMHRGV2aWNlcxYMTElOWiBEZXZpY2VzMDwwLTELMAkG -+ A1UEBhMCTloxDTALBgNVBAoTBExJTloxDzANBgNVBAsTBlBlb3BsZRYLTElOWiBQZW9wbGUwVDA0M -+ QswCQYDVQQGEwJVUzElMCMGA1UEChMcTWFnZWxsYW4gSGVhbHRoIFNlcnZpY2VzIEluYxYcTWFnZW -+ xsYW4gSGVhbHRoIFNlcnZpY2VzIEluYzBnMFExFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEUMBIGCgm -+ SJomT8ixkARkWBHRlc3QxEzARBgNVBAsTClRlc3QgVXNlcnMxDTALBgNVBAcTBFRlc3QWEkNMUyBU -+ ZXN0IFVzZXIgVGVzdDBEMDoxCzAJBgNVBAYTAnVzMSswKQYDVQQKEyJGZWRlcmFsIEhvbWUgTG9hb -+ iBCYW5rIG9mIE5ldyBZb3JrFgZGSExCTlkwWjBKMQswCQYDVQQGEwJ1czErMCkGA1UEChMiRmVkZX -+ JhbCBIb21lIExvYW4gQmFuayBvZiBOZXcgWW9yazEOMAwGA1UECxMFMUxpbmsWDEZITEJOWSAxTGl -+ uazBcMEsxCzAJBgNVBAYTAnVzMSswKQYDVQQKEyJGZWRlcmFsIEhvbWUgTG9hbiBCYW5rIG9mIE5l -+ dyBZb3JrMQ8wDQYDVQQLEwZBZG1pbnMWDUZITEJOWSBBZG1pbnMwSAYJKoZIhvZ9B0QQMTswOTAQA -+ gEAAgEAAgEIAgEPAwIDeDAQAgEAAgEAAgEIAgEKAwIAeTAQAgEAAgEAAgEIAgEKAwIAeQMBADBxBg -+ kqhkiG9n0HTUAxZAxiQUVTLUNCQy0xMjgsIEFFUy1DQkMtMjU2LCBBRVMtR0NNLTEyOCwgQUVTLUd -+ DTS0yNTYsIFRSSVBMRURFUy1DQkMtMTkyLCBDQVNUNS1DQkMtODAsIENBU1Q1LUNCQy0xMjgwdgYJ -+ KoZIhvZ9B01BMWkMZ0VDRFNBLVJFQ09NTUVOREVELCBSU0FQU1MtUkVDT01NRU5ERUQsIFJTQS1SR -+ UNPTU1FTkRFRCwgRFNBLVJFQ09NTUVOREVELCBFQ0RTQS1TSEExLCBSU0EtU0hBMSwgRFNBLVNIQT -+ EwFwYJKoZIhvZ9B00QMQoECFJTQS0yMDQ4MIIWSQYJKoZIhvZ9B00AMYIWOjCCFjYwgYACAQAwADB -+ 5MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBB -+ dXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSAwHgYDVQQDExdTZWN1cml0eSBPZmZpY2VyI -+ FBvbGljeTB9AgEBMAAwdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGU -+ NlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUQWR -+ taW5pc3RyYXRvciBQb2xpY3kweAIBAjAAMHExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0 -+ MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExG -+ DAWBgNVBAMTD0VuZCBVc2VyIFBvbGljeTB9AgEDMAAwdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0 -+ VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21 -+ TdWJDQTEdMBsGA1UEAxMUQWRtaW5pc3RyYXRvciBQb2xpY3kwfQIBBDAAMHYxCzAJBgNVBAYTAlVT -+ MRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwE -+ AYDVQQLEwlEQ29tU3ViQ0ExHTAbBgNVBAMTFEFkbWluaXN0cmF0b3IgUG9saWN5MHMCAQUwADBsMQ -+ swCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXR -+ ob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRMwEQYDVQQDEwpBU0ggUG9saWN5MH0CAQYwADB2 -+ MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBd -+ XRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbG -+ ljeTB9AgEHMAAwdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnR -+ pZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUQWRtaW5p -+ c3RyYXRvciBQb2xpY3kwfAIBCDAAMHUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwI -+ AYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHDAaBg -+ NVBAMTE1NlcnZlciBMb2dpbiBQb2xpY3kwfAIBCTAAMHUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwd -+ FbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29t -+ U3ViQ0ExHDAaBgNVBAMTE1NlcnZlciBMb2dpbiBQb2xpY3kwfQIBCjAAMHYxCzAJBgNVBAYTAlVTM -+ RAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEA -+ YDVQQLEwlEQ29tU3ViQ0ExHTAbBgNVBAMTFEFkbWluaXN0cmF0b3IgUG9saWN5MIGAAgEMMAAweTE -+ LMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0 -+ aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEgMB4GA1UEAxMXQ0xTIFNlcnZlciBMb2dpbiBQb -+ 2xpY3kwgYACAQ0wADB5MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2 -+ VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSAwHgYDVQQDExdTZWN -+ 1cml0eSBPZmZpY2VyIFBvbGljeTCBgAIBDjAAMHkxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRy -+ dXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ -+ 0ExIDAeBgNVBAMTF1NlY3VyaXR5IE9mZmljZXIgUG9saWN5MH0CAQ8wADB2MQswCQYDVQQGEwJVUz -+ EQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBA -+ GA1UECxMJRENvbVN1YkNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbGljeTB9AgERMAAwdjEL -+ MAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0a -+ G9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUQWRtaW5pc3RyYXRvciBQb2xpY3 -+ kwfAIBCzAAMHUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZ -+ pY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHDAaBgNVBAMTE0NMUyBFbmQg -+ VXNlciBQb2xpY3kwfQIBEjAAMHYxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDV -+ QQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHTAbBgNVBA -+ MTFEFkbWluaXN0cmF0b3IgUG9saWN5MH0CARMwADB2MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW5 -+ 0cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1 -+ YkNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbGljeTCBgAIBFDAAMHkxCzAJBgNVBAYTAlVTM -+ RAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEA -+ YDVQQLEwlEQ29tU3ViQ0ExIDAeBgNVBAMTF0R5bkNvcnAgRW5kIFVzZXIgUG9saWN5MH8CASAwADB -+ 4MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBB -+ dXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMR8wHQYDVQQDExZDU1JFUyBSZXF1ZXN0b3IgU -+ G9saWN5MHkCASEwADByMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2 -+ VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRkwFwYDVQQDExBNRE1 -+ XUyBYQVAgUG9saWN5MEkCASIwADBCMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEhMB8G -+ A1UEAxMYU09BUCBBZG1pbiBFeHBvcnQgUG9saWN5MIGDAgEjMAAwfDELMAkGA1UEBhMCVVMxEDAOB -+ gNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBA -+ sTCURDb21TdWJDQTEjMCEGA1UEAxMaRXhwb3J0YWJsZSBFbmQgVXNlciBQb2xpY3kweAIBJDAAMHE -+ xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1 -+ dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExGDAWBgNVBAMTD0VuZCBVc2VyIFBvbGljeTB9A -+ gElMAAwdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYX -+ Rpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUQWRtaW5pc3RyYXR -+ vciBQb2xpY3kwfQIBJjAAMHYxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQL -+ ExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHTAbBgNVBAMTF -+ E1vYmlsZSBEZXZpY2UgUG9saWN5MHwCAScwADB1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cn -+ VzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkN -+ BMRwwGgYDVQQDExNTZXJ2ZXIgTG9naW4gUG9saWN5MH0CASgwADB2MQswCQYDVQQGEwJVUzEQMA4G -+ A1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UEC -+ xMJRENvbVN1YkNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbGljeTCBgQIBKTAAMHoxCzAJBg -+ NVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml -+ 0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExITAfBgNVBAMTGFNQT0MgU2VydmVyIExvZ2luIFBvbGlj -+ eTCBggIBKjAAMHsxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0a -+ WZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExIjAgBgNVBAMTGVNQT0MgQW -+ RtaW5pc3RyYXRvciBQb2xpY3kwfAIBKzAAMHUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN -+ 0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0Ex -+ HDAaBgNVBAMTE1NlcnZlciBMb2dpbiBQb2xpY3kwgZECASwwADCBiTELMAkGA1UEBhMCVVMxEDAOB -+ gNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBA -+ sTCURDb21TdWJDQTEwMC4GA1UEAxMnTWFzdGVyIExpc3QgU2lnbmVyIEFkbWluaXN0cmF0b3IgUG9 -+ saWN5MH0CAS0wADB2MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2Vy -+ dGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMR0wGwYDVQQDExRBZG1pb -+ mlzdHJhdG9yIFBvbGljeTB4AgEuMAAwcTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIj -+ AgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEYMBY -+ GA1UEAxMPRW5kIFVzZXIgUG9saWN5MH0CAS8wADB2MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50 -+ cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1Y -+ kNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbGljeTB4AgExMAAwcTELMAkGA1UEBhMCVVMxED -+ AOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgN -+ VBAsTCURDb21TdWJDQTEYMBYGA1UEAxMPRW5kIFVzZXIgUG9saWN5MH0CATIwADB2MQswCQYDVQQG -+ EwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllc -+ zESMBAGA1UECxMJRENvbVN1YkNBMR0wGwYDVQQDExRBZG1pbmlzdHJhdG9yIFBvbGljeTB8AgEwMA -+ AwdTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24 -+ gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEcMBoGA1UEAxMTU2VydmVyIExvZ2luIFBv -+ bGljeTB9AgEzMAAwdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlc -+ nRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUQWRtaW -+ 5pc3RyYXRvciBQb2xpY3kwfQIBNTAAMHYxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSI -+ wIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHTAb -+ BgNVBAMTFENhcmQgRW5kIFVzZXIgUG9saWN5MHgCATQwADBxMQswCQYDVQQGEwJVUzEQMA4GA1UEC -+ hMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRE -+ NvbVN1YkNBMRgwFgYDVQQDEw9FbmQgVXNlciBQb2xpY3kwfAIBNjAAMHUxCzAJBgNVBAYTAlVTMRA -+ wDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYD -+ VQQLEwlEQ29tU3ViQ0ExHDAaBgNVBAMTE01ETSBFbmQgVXNlciBQb2xpY3kwfAIBNzAAMHUxCzAJB -+ gNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcm -+ l0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHDAaBgNVBAMTE1NlcnZlciBMb2dpbiBQb2xpY3kwgYU -+ CATgwADB+MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNh -+ dGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSUwIwYDVQQDExxNU08gVU1TIEFkb -+ WluaXN0cmF0b3IgUG9saWN5MIJZ7wYKKoZIhvZ9B00uADGCWd8wglnbMDEwFwwSY3NjX3BpdjFrX2 -+ NhcmRhdXRoAgEnMBYwFDASDA1QaXYxS0NhcmRBdXRoAgFDMEwwEwwOY3NjX3Bpdm1peGVkXzMCASg -+ wNTAQMA4MCVBpdjFLQXV0aAIBRDAPMA0MCFBpdjJLRW5jAgFFMBAwDgwJUGl2MktTaWduAgFGMIG4 -+ MBAMC2VudF9hZF9jbHMxAgE3MIGjMIGgMA4MCUR1YWxVc2FnZQIBXDCBjTELMAkGA1UEBhMCVVMxE -+ DAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBg -+ NVBAsTCURDb21TdWJDQTE0MDIGA1UEAxMrQ0xTIDF5ciBEb21haW4gQ29udHJvbGxlciBEdWFsIFV -+ zYWdlIFBvbGljeTCBuDAQDAtlbnRfYWRfY2xzMgIBODCBozCBoDAODAlEdWFsVXNhZ2UCAV0wgY0x -+ CzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1d -+ Ghvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExNDAyBgNVBAMTK0NMUyAyeXIgRG9tYWluIENvbn -+ Ryb2xsZXIgRHVhbCBVc2FnZSBQb2xpY3kwdTARDAxlbnRfYWRfY2xzMm0CAVIwTjAjMBAMCkVuY3J -+ 5cHRpb24CAgCQog8MCkVuY3J5cHRpb24CAQEwJzASDAxWZXJpZmljYXRpb24CAgCRohEMDFZlcmlm -+ aWNhdGlvbgIBAqIQDAtlbnRfZGVmYXVsdAIBAzCBvjASDA1lbnRfYWRfY2xzMm1hAgFUMIGnMIGkM -+ A8MCUR1YWxVc2FnZQICAJQwgZAxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQ -+ QLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExNzA1BgNVBAM -+ TLkNMUyAybW9udGggRG9tYWluIENvbnRyb2xsZXIgRHVhbCBVc2FnZSBQb2xpY3kwgbAwDgwJZW50 -+ X2FkX2RjAgF4MIGdMIGaMBAMCkR1YWwgVXNhZ2UCAgDSMIGFMQswCQYDVQQGEwJVUzEQMA4GA1UEC -+ hMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRE -+ NvbVN1YkNBMSwwKgYDVQQDEyNFbnRlcnByaXNlIERvbWFpbiBDb250cm9sbGVyIFBvbGljeTBHMBk -+ ME2VudF9hZG1zcnZjc191bXNfZWECAgCLMCowEjAQDApFbmNyeXB0aW9uAgIA9DAUMBIMDFZlcmlm -+ aWNhdGlvbgICAPUwRTAZDBRlbnRfYWRtc3J2Y3NfdXNlcnJlZwIBEjAoMBEwDwwKRW5jcnlwdGlvb -+ gIBHjATMBEMDFZlcmlmaWNhdGlvbgIBHzCBzzAZDBRlbnRfYWRtc3J2Y3NfdXNybWdtdAIBETCBsT -+ ARMA8MCkVuY3J5cHRpb24CARwwgZswEQwMVmVyaWZpY2F0aW9uAgEdMIGFMQswCQYDVQQGEwJVUzE -+ QMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAG -+ A1UECxMJRENvbVN1YkNBMSwwKgYDVQQDEyNUcnVlUGFzcyBTZXJ2ZXIgVmVyaWZpY2F0aW9uIFBvb -+ GljeTA6MA4MCWVudF9iYXNpYwIBJjAoMBEwDwwKRW5jcnlwdGlvbgIBQTATMBEMDFZlcmlmaWNhdG -+ lvbgIBQjCCATkwDQwIZW50X2NsczECAS8wggEmMIGOMA8MCkVuY3J5cHRpb24CAVIwezELMAkGA1U -+ EBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRp -+ ZXMxEjAQBgNVBAsTCURDb21TdWJDQTEiMCAGA1UEAxMZQ0xTIDF5ciBFbmNyeXB0aW9uIFBvbGlje -+ TCBkjARDAxWZXJpZmljYXRpb24CAVMwfTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIj -+ AgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEkMCI -+ GA1UEAxMbQ0xTIDF5ciBWZXJpZmljYXRpb24gUG9saWN5MIIBOTANDAhlbnRfY2xzMgIBMDCCASYw -+ gY4wDwwKRW5jcnlwdGlvbgIBVDB7MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA -+ 1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSIwIAYDVQ -+ QDExlDTFMgMnlyIEVuY3J5cHRpb24gUG9saWN5MIGSMBEMDFZlcmlmaWNhdGlvbgIBVTB9MQswCQY -+ DVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3Jp -+ dGllczESMBAGA1UECxMJRENvbVN1YkNBMSQwIgYDVQQDExtDTFMgMnlyIFZlcmlmaWNhdGlvbiBQb -+ 2xpY3kwQDASDA1lbnRfY2xzX2FkbWluAgFXMCowEjAQDApFbmNyeXB0aW9uAgIAmDAUMBIMDFZlcm -+ lmaWNhdGlvbgICAJkwggFPMBMMDmVudF9jbHNfYWRtaW4yAgFWMIIBNjCBljAQDApFbmNyeXB0aW9 -+ uAgIAljCBgTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmlj -+ YXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEoMCYGA1UEAxMfQ0xTIEFkbWluI -+ DJ5ciBFbmNyeXB0aW9uIFBvbGljeTCBmjASDAxWZXJpZmljYXRpb24CAgCXMIGDMQswCQYDVQQGEw -+ JVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczE -+ SMBAGA1UECxMJRENvbVN1YkNBMSowKAYDVQQDEyFDTFMgQWRtaW4gMnlyIFZlcmlmaWNhdGlvbiBQ -+ b2xpY3kwgbgwFwwSZW50X2Ntc2NsaWVudF9jbHMxAgExMIGcMIGZMA8MCkR1YWwgVXNhZ2UCAVYwg -+ YUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIE -+ F1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExLDAqBgNVBAMTI0NMUyAxeXIgQUkgQ2xpZW5 -+ 0IER1YWwgVXNhZ2UgUG9saWN5MIG/MBkMFGVudF9jbXNjbGllbnRfY2xzMV9mAgEzMIGhMIGeMA8M -+ CkR1YWwgVXNhZ2UCAVgwgYoxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLE -+ xlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExMTAvBgNVBAMTKE -+ NMUyAxeXIgQUkgQ2xpZW50IEZpbGUgRHVhbCBVc2FnZSBQb2xpY3kwgbgwFwwSZW50X2Ntc2NsaWV -+ udF9jbHMyAgEyMIGcMIGZMA8MCkR1YWwgVXNhZ2UCAVcwgYUxCzAJBgNVBAYTAlVTMRAwDgYDVQQK -+ EwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ -+ 29tU3ViQ0ExLDAqBgNVBAMTI0NMUyAyeXIgQUkgQ2xpZW50IER1YWwgVXNhZ2UgUG9saWN5MIG/MB -+ kMFGVudF9jbXNjbGllbnRfY2xzMl9mAgE0MIGhMIGeMA8MCkR1YWwgVXNhZ2UCAVkwgYoxCzAJBgN -+ VBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -+ aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExMTAvBgNVBAMTKENMUyAyeXIgQUkgQ2xpZW50IEZpbGUgR -+ HVhbCBVc2FnZSBQb2xpY3kwLjAXDBJlbnRfY21zY2xpZW50X3NrZHUCASowEzARMA8MCkR1YWwgVX -+ NhZ2UCAUkwMDAZDBRlbnRfY21zY2xpZW50X3NrZHVfZgIBKzATMBEwDwwKRHVhbCBVc2FnZQIBSjC -+ BuDAXDBJlbnRfY21zc2VydmVyX2NsczECATUwgZwwgZkwDwwKRHVhbCBVc2FnZQIBWjCBhTELMAkG -+ A1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9ya -+ XRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEsMCoGA1UEAxMjQ0xTIDF5ciBBSSBTZXJ2ZXIgRHVhbC -+ BVc2FnZSBQb2xpY3kwgbgwFwwSZW50X2Ntc3NlcnZlcl9jbHMyAgE2MIGcMIGZMA8MCkR1YWwgVXN -+ hZ2UCAVswgYUxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZp -+ Y2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExLDAqBgNVBAMTI0NMUyAyeXIgQ -+ UkgU2VydmVyIER1YWwgVXNhZ2UgUG9saWN5MC4wFwwSZW50X2Ntc3NlcnZlcl9za2R1AgEsMBMwET -+ APDApEdWFsIFVzYWdlAgFLMEYwGAwSZW50X2NzcmVzX2FwcHJvdmVyAgIAjDAqMBIwEAwKRW5jcnl -+ wdGlvbgICAPYwFDASDAxWZXJpZmljYXRpb24CAgD3MEYwGAwTZW50X2NzcmVzX3JlcXVlc3RvcgIB -+ bzAqMBIwEAwKRW5jcnlwdGlvbgICAMUwFDASDAxWZXJpZmljYXRpb24CAgDGMDwwEAwLZW50X2RlZ -+ mF1bHQCAQMwKDARMA8MCkVuY3J5cHRpb24CAQEwEzARDAxWZXJpZmljYXRpb24CAQIwggE8MBAMC2 -+ VudF9kZXNrdG9wAgEHMIIBJjCBjjAPDApFbmNyeXB0aW9uAgEJMHsxCzAJBgNVBAYTAlVTMRAwDgY -+ DVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQL -+ EwlEQ29tU3ViQ0ExIjAgBgNVBAMTGVNhZmVOZXQgRW5jcnlwdGlvbiBQb2xpY3kwgZIwEQwMVmVya -+ WZpY2F0aW9uAgEKMH0xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZX -+ J0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExJDAiBgNVBAMTG1NhZmV -+ OZXQgVmVyaWZpY2F0aW9uIFBvbGljeTCBpDAVDBBlbnRfZHVfYmFzaWNfZWt1AgFtMIGKMIGHMBAM -+ CkR1YWwgVXNhZ2UCAgDCMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLE -+ xlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExGjAYBgNVBAMTEU -+ R1YWwgVXNhZ2UgUG9saWN5MEMwFQwQZW50X2VhY2NhdHRhY2hlZAIBaDAqMBIwEAwKRW5jcnlwdGl -+ vbgICALgwFDASDAxWZXJpZmljYXRpb24CAgC5MD0wDwwKZW50X2VhY2NvbgIBajAqMBIwEAwKRW5j -+ cnlwdGlvbgICALwwFDASDAxWZXJpZmljYXRpb24CAgC9MEUwFwwSZW50X2VhY2NzdGFuZGFsb25lA -+ gFpMCowEjAQDApFbmNyeXB0aW9uAgIAujAUMBIMDFZlcmlmaWNhdGlvbgICALswggGiMAwMB2VudF -+ 9lZnMCARUwggGQMHgwCAwDRUZTAgEnMGwxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSI -+ wIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExEzAR -+ BgNVBAMTCkVGUyBQb2xpY3kwgYYwDwwKRW5jcnlwdGlvbgIBJTBzMQswCQYDVQQGEwJVUzEQMA4GA -+ 1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECx -+ MJRENvbVN1YkNBMRowGAYDVQQDExFFbmNyeXB0aW9uIFBvbGljeTCBijARDAxWZXJpZmljYXRpb24 -+ CASYwdTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRp -+ b24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEcMBoGA1UEAxMTVmVyaWZpY2F0aW9uI -+ FBvbGljeTBEMBgME2VudF9lc3Zwbl9jb21tZWRvaWQCASUwKDARMA8MCkVuY3J5cHRpb24CAT8wEz -+ ARDAxWZXJpZmljYXRpb24CAUAwggE7MA8MCmVudF9ldG9rZW4CAWwwggEmMIGOMBAMCkVuY3J5cHR -+ pb24CAgDAMHoxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZp -+ Y2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExITAfBgNVBAMTGGVUb2tlbiBFb -+ mNyeXB0aW9uIFBvbGljeTCBkjASDAxWZXJpZmljYXRpb24CAgDBMHwxCzAJBgNVBAYTAlVTMRAwDg -+ YDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQ -+ LEwlEQ29tU3ViQ0ExIzAhBgNVBAMTGmVUb2tlbiBWZXJpZmljYXRpb24gUG9saWN5MIIBOTAPDApl -+ bnRfZXhwb3J0AgEGMIIBJDCBjTAPDApFbmNyeXB0aW9uAgEHMHoxCzAJBgNVBAYTAlVTMRAwDgYDV -+ QQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEw -+ lEQ29tU3ViQ0ExITAfBgNVBAMUGEVuY3J5cHRpb24gUG9saWN5X0V4cG9ydDCBkTARDAxWZXJpZml -+ jYXRpb24CAQgwfDELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRp -+ ZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEjMCEGA1UEAxQaVmVyaWZpY -+ 2F0aW9uIFBvbGljeV9FeHBvcnQwggE9MBQMD2VudF9nZW1hbHRvX2NzcAIBXjCCASMwgYowEAwKRW -+ 5jcnlwdGlvbgICAKswdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUN -+ lcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMBsGA1UEAxMUR00g -+ RW5jcnlwdGlvbiBQb2xpY3kwgZMwEgwMVmVyaWZpY2F0aW9uAgIArDB9MQswCQYDVQQGEwJVUzEQM -+ A4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1 -+ UECxMJRENvbVN1YkNBMSQwIgYDVQQDExtHZW1hbHRvIFZlcmlmaWNhdGlvbiBQb2xpY3kwgb8wFgw -+ RZW50X2lpc19za2R1X2NsczECATkwgaQwgaEwDwwKRHVhbCBVc2FnZQIBXjCBjTELMAkGA1UEBhMC -+ VVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxE -+ jAQBgNVBAsTCURDb21TdWJDQTE0MDIGA1UEAxMrQ0xTIDF5ciBJSVMgRHVhbCBVc2FnZSBObyBLZX -+ kgQmFja3VwIFBvbGljeTCBvzAWDBFlbnRfaWlzX3NrZHVfY2xzMgIBOjCBpDCBoTAPDApEdWFsIFV -+ zYWdlAgFfMIGNMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlm -+ aWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMTQwMgYDVQQDEytDTFMgMnlyI -+ ElJUyBEdWFsIFVzYWdlIE5vIEtleSBCYWNrdXAgUG9saWN5MHswFwwSZW50X2lpc19za2R1X2Nscz -+ JtAgFTME4wIzAQDApFbmNyeXB0aW9uAgIAkqIPDApFbmNyeXB0aW9uAgEBMCcwEgwMVmVyaWZpY2F -+ 0aW9uAgIAk6IRDAxWZXJpZmljYXRpb24CAQKiEAwLZW50X2RlZmF1bHQCAQMwgcUwGAwTZW50X2lp -+ c19za2R1X2NsczJtYQIBVTCBqDCBpTAQDApEdWFsIFVzYWdlAgIAlTCBkDELMAkGA1UEBhMCVVMxE -+ DAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBg -+ NVBAsTCURDb21TdWJDQTE3MDUGA1UEAxMuQ0xTIDJtb250aCBJSVMgRHVhbCBVc2FnZSBObyBLZXk -+ gQmFja3VwIFBvbGljeTCBpzAQDAtlbnRfbWFjaGluZQIBeTCBkjCBjzAQDApEdWFsIFVzYWdlAgIA -+ 0zB7MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvb -+ iBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSIwIAYDVQQDExlFbnRlcnByaXNlIE1hY2 -+ hpbmUgUG9saWN5MEAwEgwNZW50X21kbXdzX2NsaQIBcDAqMBIwEAwKRW5jcnlwdGlvbgICAMcwFDA -+ SDAxWZXJpZmljYXRpb24CAgDIMEIwFAwPZW50X21saXN0X2FkbWluAgF/MCowEjAQDApFbmNyeXB0 -+ aW9uAgIA3jAUMBIMDFZlcmlmaWNhdGlvbgICAN8wggE5MBUMEGVudF9tbGlzdF9zaWduZXICAX4wg -+ gEeMIGHMBAMCkVuY3J5cHRpb24CAgDcMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MS -+ IwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExGjA -+ YBgNVBAMTEUVuY3J5cHRpb24gUG9saWN5MIGRMBIMDFZlcmlmaWNhdGlvbgICAN0wezELMAkGA1UE -+ BhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZ -+ XMxEjAQBgNVBAsTCURDb21TdWJDQTEiMCAGA1UEAxMZTWFzdGVyIExpc3QgU2lnbmVyIFBvbGljeT -+ CCAeQwGAwTZW50X21zX3NjX2NhcGlfY2xzMQIBLTCCAcYwgZ0wDwwKRHVhbCBVc2FnZQIBTDCBiTE -+ LMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0 -+ aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEwMC4GA1UEAxMnQ0xTIDF5ciBEdWFsIFVzYWdlI -+ E5vIEtleSBCYWNrdXAgUG9saWN5MIGOMA8MCkVuY3J5cHRpb24CAU4wezELMAkGA1UEBhMCVVMxED -+ AOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgN -+ VBAsTCURDb21TdWJDQTEiMCAGA1UEAxMZQ0xTIDF5ciBFbmNyeXB0aW9uIFBvbGljeTCBkjARDAxW -+ ZXJpZmljYXRpb24CAU0wfTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTG -+ UNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEkMCIGA1UEAxMbQ0 -+ xTIDF5ciBWZXJpZmljYXRpb24gUG9saWN5MIIB5DAYDBNlbnRfbXNfc2NfY2FwaV9jbHMyAgEuMII -+ BxjCBnTAPDApEdWFsIFVzYWdlAgFPMIGJMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEi -+ MCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMTAwL -+ gYDVQQDEydDTFMgMnlyIER1YWwgVXNhZ2UgTm8gS2V5IEJhY2t1cCBQb2xpY3kwgY4wDwwKRW5jcn -+ lwdGlvbgIBUTB7MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGl -+ maWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSIwIAYDVQQDExlDTFMgMnly -+ IEVuY3J5cHRpb24gUG9saWN5MIGSMBEMDFZlcmlmaWNhdGlvbgIBUDB9MQswCQYDVQQGEwJVUzEQM -+ A4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1 -+ UECxMJRENvbVN1YkNBMSQwIgYDVQQDExtDTFMgMnlyIFZlcmlmaWNhdGlvbiBQb2xpY3kwggHyMBk -+ MFGVudF9tc19zY19jYXBpX2NsczJtAgFRMIIB0zCBoTAQDApEdWFsIFVzYWdlAgIAjTCBjDELMAkG -+ A1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9ya -+ XRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEzMDEGA1UEAxMqQ0xTIDJtb250aCBEdWFsIFVzYWdlIE -+ 5vIEtleSBCYWNrdXAgUG9saWN5MIGSMBAMCkVuY3J5cHRpb24CAgCPMH4xCzAJBgNVBAYTAlVTMRA -+ wDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYD -+ VQQLEwlEQ29tU3ViQ0ExJTAjBgNVBAMTHENMUyAybW9udGggRW5jcnlwdGlvbiBQb2xpY3kwgZcwE -+ gwMVmVyaWZpY2F0aW9uAgIAjjCBgDELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBg -+ NVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEnMCUGA1U -+ EAxMeQ0xTIDJtb250aCBWZXJpZmljYXRpb24gUG9saWN5MIIB5zAYDBNlbnRfbXNfc2NfY2FwaV9j -+ bHM0AgFPMIIByTCBnjAQDApEdWFsIFVzYWdlAgIAhzCBiTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB -+ 0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb2 -+ 1TdWJDQTEwMC4GA1UEAxMnQ0xTIDR5ciBEdWFsIFVzYWdlIE5vIEtleSBCYWNrdXAgUG9saWN5MIG -+ PMBAMCkVuY3J5cHRpb24CAgCJMHsxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYD -+ VQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExIjAgBgNVB -+ AMTGUNMUyA0eXIgRW5jcnlwdGlvbiBQb2xpY3kwgZMwEgwMVmVyaWZpY2F0aW9uAgIAiDB9MQswCQ -+ YDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3J -+ pdGllczESMBAGA1UECxMJRENvbVN1YkNBMSQwIgYDVQQDExtDTFMgNHlyIFZlcmlmaWNhdGlvbiBQ -+ b2xpY3kwggHnMBgME2VudF9tc19zY19jYXBpX2NsczUCAVAwggHJMIGeMBAMCkR1YWwgVXNhZ2UCA -+ gCKMIGJMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdG -+ lvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMTAwLgYDVQQDEydDTFMgNXlyIER1YWw -+ gVXNhZ2UgTm8gS2V5IEJhY2t1cCBQb2xpY3kwgY8wEAwKRW5jcnlwdGlvbgICAIwwezELMAkGA1UE -+ BhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZ -+ XMxEjAQBgNVBAsTCURDb21TdWJDQTEiMCAGA1UEAxMZQ0xTIDV5ciBFbmNyeXB0aW9uIFBvbGljeT -+ CBkzASDAxWZXJpZmljYXRpb24CAgCLMH0xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSI -+ wIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExJDAi -+ BgNVBAMTG0NMUyA1eXIgVmVyaWZpY2F0aW9uIFBvbGljeTCCAfgwGAwTZW50X21zX3NjX2NsczRfM -+ TAyNAIBXDCCAdowgaMwEAwKRHVhbCBVc2FnZQICAKUwgY4xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEw -+ dFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29 -+ tU3ViQ0ExNTAzBgNVBAMTLENMUyAxMDI0IDR5ciBEdWFsIFVzYWdlIE5vIEtleSBCYWNrdXAgUG9s -+ aWN5MIGVMBAMCkVuY3J5cHRpb24CAgCnMIGAMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzd -+ DEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMS -+ cwJQYDVQQDEx5DTFMgMTAyNCA0eXIgRW5jcnlwdGlvbiBQb2xpY3kwgZkwEgwMVmVyaWZpY2F0aW9 -+ uAgIApjCBgjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmlj -+ YXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEpMCcGA1UEAxMgQ0xTIDEwMjQgN -+ HlyIFZlcmlmaWNhdGlvbiBQb2xpY3kwggH4MBgME2VudF9tc19zY19jbHM0XzIwNDgCAVowggHaMI -+ GjMBAMCkR1YWwgVXNhZ2UCAgCfMIGOMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCA -+ GA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMTUwMwYD -+ VQQDEyxDTFMgMjA0OCA0eXIgRHVhbCBVc2FnZSBObyBLZXkgQmFja3VwIFBvbGljeTCBlTAQDApFb -+ mNyeXB0aW9uAgIAoTCBgDELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGU -+ NlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEnMCUGA1UEAxMeQ0x -+ TIDIwNDggNHlyIEVuY3J5cHRpb24gUG9saWN5MIGZMBIMDFZlcmlmaWNhdGlvbgICAKAwgYIxCzAJ -+ BgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvc -+ ml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExKTAnBgNVBAMTIENMUyAyMDQ4IDR5ciBWZXJpZmljYX -+ Rpb24gUG9saWN5MIIB+DAYDBNlbnRfbXNfc2NfY2xzNV8xMDI0AgFdMIIB2jCBozAQDApEdWFsIFV -+ zYWdlAgIAqDCBjjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRp -+ ZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTE1MDMGA1UEAxMsQ0xTIDEwM -+ jQgNXlyIER1YWwgVXNhZ2UgTm8gS2V5IEJhY2t1cCBQb2xpY3kwgZUwEAwKRW5jcnlwdGlvbgICAK -+ owgYAxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9 -+ uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExJzAlBgNVBAMTHkNMUyAxMDI0IDV5ciBF -+ bmNyeXB0aW9uIFBvbGljeTCBmTASDAxWZXJpZmljYXRpb24CAgCpMIGCMQswCQYDVQQGEwJVUzEQM -+ A4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1 -+ UECxMJRENvbVN1YkNBMSkwJwYDVQQDEyBDTFMgMTAyNCA1eXIgVmVyaWZpY2F0aW9uIFBvbGljeTC -+ CAfgwGAwTZW50X21zX3NjX2NsczVfMjA0OAIBWzCCAdowgaMwEAwKRHVhbCBVc2FnZQICAKIwgY4x -+ CzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1d -+ Ghvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExNTAzBgNVBAMTLENMUyAyMDQ4IDV5ciBEdWFsIF -+ VzYWdlIE5vIEtleSBCYWNrdXAgUG9saWN5MIGVMBAMCkVuY3J5cHRpb24CAgCkMIGAMQswCQYDVQQ -+ GEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGll -+ czESMBAGA1UECxMJRENvbVN1YkNBMScwJQYDVQQDEx5DTFMgMjA0OCA1eXIgRW5jcnlwdGlvbiBQb -+ 2xpY3kwgZkwEgwMVmVyaWZpY2F0aW9uAgIAozCBgjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudH -+ J1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJ -+ DQTEpMCcGA1UEAxMgQ0xTIDIwNDggNXlyIFZlcmlmaWNhdGlvbiBQb2xpY3kwggHpMBcMEmVudF9t -+ c19zY19jbHNfMjA0OAIBWDCCAcwwgZ8wEAwKRHVhbCBVc2FnZQICAJowgYoxCzAJBgNVBAYTAlVTM -+ RAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEA -+ YDVQQLEwlEQ29tU3ViQ0ExMTAvBgNVBAMTKENMUyAyMDQ4IER1YWwgVXNhZ2UgTm8gS2V5IEJhY2t -+ 1cCBQb2xpY3kwgZAwEAwKRW5jcnlwdGlvbgICAJwwfDELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0Vu -+ dHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21Td -+ WJDQTEjMCEGA1UEAxMaQ0xTIDIwNDggRW5jcnlwdGlvbiBQb2xpY3kwgZQwEgwMVmVyaWZpY2F0aW -+ 9uAgIAmzB+MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWN -+ hdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSUwIwYDVQQDExxDTFMgMjA0OCBW -+ ZXJpZmljYXRpb24gUG9saWN5MIG1MBgME2VudF9tc19zbXJ0Y3JkX2NhcGkCAQ8wgZgwgZUwDwwKR -+ HVhbCBVc2FnZQIBGTCBgTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGU -+ NlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEoMCYGA1UEAxMfRHV -+ hbCBVc2FnZSBObyBLZXkgQmFja3VwIFBvbGljeTCCAakwEAwKZW50X21zY2FwaQICAIEwggGTMHkw -+ CQwDRUZTAgIA4zBsMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2Vyd -+ GlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRMwEQYDVQQDEwpFRlMgUG -+ 9saWN5MIGHMBAMCkVuY3J5cHRpb24CAgDhMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN -+ 0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0Ex -+ GjAYBgNVBAMTEUVuY3J5cHRpb24gUG9saWN5MIGLMBIMDFZlcmlmaWNhdGlvbgICAOIwdTELMAkGA -+ 1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaX -+ RpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEcMBoGA1UEAxMTVmVyaWZpY2F0aW9uIFBvbGljeTBDMBc -+ MEmVudF9tc2Z0X3NtYXJ0Y2FyZAIBDjAoMBEwDwwKRW5jcnlwdGlvbgIBFzATMBEMDFZlcmlmaWNh -+ dGlvbgIBGDA/MBMMDmVudF9tc2dzY2FubmVyAgENMCgwETAPDApFbmNyeXB0aW9uAgEVMBMwEQwMV -+ mVyaWZpY2F0aW9uAgEWMD4wEgwNZW50X21zZ3NlcnZlcgIBDDAoMBEwDwwKRW5jcnlwdGlvbgIBEz -+ ATMBEMDFZlcmlmaWNhdGlvbgIBFDBAMBIMDGVudF9tc29hZG1pbgICAIkwKjASMBAMCkVuY3J5cHR -+ pb24CAgDxMBQwEgwMVmVyaWZpY2F0aW9uAgIA8DCCATkwFQwQZW50X21zdHdva2V5cGFpcgIBWTCC -+ AR4wgYowEAwKRW5jcnlwdGlvbgICAJ0wdjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxI -+ jAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEdMB -+ sGA1UEAxMUR00gRW5jcnlwdGlvbiBQb2xpY3kwgY4wEgwMVmVyaWZpY2F0aW9uAgIAnjB4MQswCQY -+ DVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3Jp -+ dGllczESMBAGA1UECxMJRENvbVN1YkNBMR8wHQYDVQQDExZHTSBWZXJpZmljYXRpb24gUG9saWN5M -+ IIBvjARDAxlbnRfbm9ucmVwdWQCARQwggGnMIGGMA8MCkVuY3J5cHRpb24CASIwczELMAkGA1UEBh -+ MCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXM -+ xEjAQBgNVBAsTCURDb21TdWJDQTEaMBgGA1UEAxMRRW5jcnlwdGlvbiBQb2xpY3kwgY4wEwwOTm9u -+ cmVwdWRpYXRpb24CASQwdzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTG -+ UNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEeMBwGA1UEAxMVTm -+ 9ucmVwdWRpYXRpb24gUG9saWN5MIGKMBEMDFZlcmlmaWNhdGlvbgIBIzB1MQswCQYDVQQGEwJVUzE -+ QMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAG -+ A1UECxMJRENvbVN1YkNBMRwwGgYDVQQDExNWZXJpZmljYXRpb24gUG9saWN5MIICQDAZDBRlbnRfb -+ m9ucmVwdWRfYW5kX2VmcwIBFzCCAiEweDAIDANFRlMCAS0wbDELMAkGA1UEBhMCVVMxEDAOBgNVBA -+ oTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCUR -+ Db21TdWJDQTETMBEGA1UEAxMKRUZTIFBvbGljeTCBhjAPDApFbmNyeXB0aW9uAgEqMHMxCzAJBgNV -+ BAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0a -+ WVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExGjAYBgNVBAMTEUVuY3J5cHRpb24gUG9saWN5MIGOMBMMDk -+ 5vbnJlcHVkaWF0aW9uAgEsMHcxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQ -+ LExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExHjAcBgNVBAMT -+ FU5vbnJlcHVkaWF0aW9uIFBvbGljeTCBijARDAxWZXJpZmljYXRpb24CASswdTELMAkGA1UEBhMCV -+ VMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEj -+ AQBgNVBAsTCURDb21TdWJDQTEcMBoGA1UEAxMTVmVyaWZpY2F0aW9uIFBvbGljeTA5MA0MCGVudF9 -+ vY3NwAgEpMCgwETAPDApFbmNyeXB0aW9uAgFHMBMwEQwMVmVyaWZpY2F0aW9uAgFIMD0wEQwMZW50 -+ X3Byb2ZzcnZyAgEFMCgwETAPDApFbmNyeXB0aW9uAgEFMBMwEQwMVmVyaWZpY2F0aW9uAgEGMDgwD -+ AwHZW50X3JkcAIBQDAoMBEwDwwKRW5jcnlwdGlvbgIBaTATMBEMDFZlcmlmaWNhdGlvbgIBajCBqj -+ ASDA1lbnRfc2lnbl9uaXN0AgFyMIGTMIGQMBIMDFZlcmlmaWNhdGlvbgICAMowejELMAkGA1UEBhM -+ CVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMx -+ EjAQBgNVBAsTCURDb21TdWJDQTEhMB8GA1UEAxMYTklTVCBWZXJpZmljYXRpb24gUG9saWN5MIGkM -+ BYMEWVudF9za3BfZHVhbHVzYWdlAgEYMIGJMIGGMA8MCkR1YWwgVXNhZ2UCAS4wczELMAkGA1UEBh -+ MCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXM -+ xEjAQBgNVBAsTCURDb21TdWJDQTEaMBgGA1UEAxMRRHVhbCBVc2FnZSBQb2xpY3kwLTATDA1lbnRf -+ c2twbm9ucmVwAgIAgDAWMBQwEgwMVmVyaWZpY2F0aW9uAgIA4DAwMBgMEmVudF9za3Bub25yZXBfY -+ XV0aAICAIYwFDASMBAMCkR1YWwgVXNhZ2UCAgDrMEEwEwwOZW50X3Nwb2NfYWRtaW4CAXwwKjASMB -+ AMCkVuY3J5cHRpb24CAgDYMBQwEgwMVmVyaWZpY2F0aW9uAgIA2TBCMBQMD2VudF9zcG9jX2NsaWV -+ udAIBejAqMBIwEAwKRW5jcnlwdGlvbgICANQwFDASDAxWZXJpZmljYXRpb24CAgDVMD4wEAwLZW50 -+ X3Nwb2NfZHYCAX0wKjASMBAMCkVuY3J5cHRpb24CAgDaMBQwEgwMVmVyaWZpY2F0aW9uAgIA2zBCM -+ BQMD2VudF9zcG9jX3NlcnZlcgIBezAqMBIwEAwKRW5jcnlwdGlvbgICANYwFDASDAxWZXJpZmljYX -+ Rpb24CAgDXMIG+MBMMDWVudF9zc2xfYmFzaWMCAgCIMIGmMBIwEAwKRW5jcnlwdGlvbgICAO8wgY8 -+ wEgwMVmVyaWZpY2F0aW9uAgIA7jB5MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAG -+ A1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSAwHgYDV -+ QQDFBdWZXJpZmljYXRpb25fcDEwIFBvbGljeTB7MBIMDGVudF9zc2xfY2VydAICAIcwUDAkMBAMCk -+ VuY3J5cHRpb24CAgDsohAMCkVuY3J5cHRpb24CAgDvMCgwEgwMVmVyaWZpY2F0aW9uAgIA7aISDAx -+ WZXJpZmljYXRpb24CAgDuohMMDWVudF9zc2xfYmFzaWMCAgCIMIIBKDAXDBJlbnRfc3RhbmRhbG9u -+ ZV9lZnMCARYwggELMIGLMBAMC0NNUCBTaWduaW5nAgEpMHcxCzAJBgNVBAYTAlVTMRAwDgYDVQQKE -+ wdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ2 -+ 9tU3ViQ0ExHjAcBgNVBAMTFU1TIENNUCBTaWduaW5nIFBvbGljeTB7MAgMA0VGUwIBKDBvMQswCQY -+ DVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3Jp -+ dGllczESMBAGA1UECxMJRENvbVN1YkNBMRYwFAYDVQQDEw1NUyBFRlMgUG9saWN5MD4wEgwNZW50X -+ 3RpbWVzdGFtcAIBBDAoMBEwDwwKRW5jcnlwdGlvbgIBAzATMBEMDFZlcmlmaWNhdGlvbgIBBDBDMB -+ UMEGVudF90aW1lc3RhbXBpbmcCAXcwKjASMBAMCkVuY3J5cHRpb24CAgDQMBQwEgwMVmVyaWZpY2F -+ 0aW9uAgIA0TCBxzARDAxlbnRfdHJ1ZXBhc3MCAQgwgbEwETAPDApFbmNyeXB0aW9uAgELMIGbMBEM -+ DFZlcmlmaWNhdGlvbgIBDDCBhTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVB -+ AsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEsMCoGA1UEAx -+ MjVHJ1ZVBhc3MgU2VydmVyIFZlcmlmaWNhdGlvbiBQb2xpY3kwgc0wFwwSZW50X3RydWVwYXNzX21 -+ 1bHRpAgEJMIGxMBEwDwwKRW5jcnlwdGlvbgIBDTCBmzARDAxWZXJpZmljYXRpb24CAQ4wgYUxCzAJ -+ BgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvc -+ ml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExLDAqBgNVBAMTI1RydWVQYXNzIFNlcnZlciBWZXJpZm -+ ljYXRpb24gUG9saWN5MIIBLzATDA5lbnRfdHdva2V5cGFpcgIBEzCCARYwgYYwDwwKRW5jcnlwdGl -+ vbgIBIDBzMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNh -+ dGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRowGAYDVQQDExFFbmNyeXB0aW9uI -+ FBvbGljeTCBijARDAxWZXJpZmljYXRpb24CASEwdTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudH -+ J1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJ -+ DQTEcMBoGA1UEAxMTVmVyaWZpY2F0aW9uIFBvbGljeTCCAUMwFwwSZW50X3R3b2tleXBhaXJfcDEw -+ AgEkMIIBJjCBjjATDA5FbmNyeXB0aW9uX3AxMAIBPTB3MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHR -+ W50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbV -+ N1YkNBMR4wHAYDVQQDFBVFbmNyeXB0aW9uX3AxMCBQb2xpY3kwgZIwFQwQVmVyaWZpY2F0aW9uX3A -+ xMAIBPjB5MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNh -+ dGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMSAwHgYDVQQDFBdWZXJpZmljYXRpb -+ 25fcDEwIFBvbGljeTBBMBMMDWVudF91bXNfYWRtaW4CAgCKMCowEjAQDApFbmNyeXB0aW9uAgIA8j -+ AUMBIMDFZlcmlmaWNhdGlvbgICAPMwOzAPDAplbnRfeGFwc3J2AgEQMCgwETAPDApFbmNyeXB0aW9 -+ uAgEaMBMwEQwMVmVyaWZpY2F0aW9uAgEbMIGuMBUMEGVwYXNzX2RvY19zaWduZXICAWQwgZQwgZEw -+ FQwPRG9jdW1lbnQgU2lnbmVyAgIAtzB4MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiM -+ CAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMR8wHQ -+ YDVQQDExZEb2N1bWVudCBTaWduZXIgUG9saWN5MIGzMBoMFGVwYXNzX2RvY19zaWduZXJfZHRsAgI -+ AhDCBlDCBkTAVDA9Eb2N1bWVudCBTaWduZXICAgDoMHgxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdF -+ bnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU -+ 3ViQ0ExHzAdBgNVBAMTFkRvY3VtZW50IFNpZ25lciBQb2xpY3kwgbYwFwwSZXBhc3NfbWxpc3Rfc2 -+ lnbmVyAgFjMIGaMIGXMBgMEk1hc3RlciBMaXN0IFNpZ25lcgICALYwezELMAkGA1UEBhMCVVMxEDA -+ OBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNV -+ BAsTCURDb21TdWJDQTEiMCAGA1UEAxMZTWFzdGVyIExpc3QgU2lnbmVyIFBvbGljeTAqMBIMDW1vY -+ mlsZV9kZXZpY2UCAXEwFDASMBAMCkR1YWwgVXNhZ2UCAgDJMIG4MBYMEW1vYmlsZV9kZXZpY2VfMW -+ twAgF2MIGdMIGaMBIMDFZlcmlmaWNhdGlvbgICAM8wgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwd -+ FbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29t -+ U3ViQ0ExKjAoBgNVBAMTIU1vYmlsZSBEZXZpY2UgVmVyaWZpY2F0aW9uIFBvbGljeTCCAVowEAwKb -+ XNfdGhyZWV5cgICAIUwggFEMIGdMBAMCkVuY3J5cHRpb24CAgDpMIGIMQswCQYDVQQGEwJVUzEQMA -+ 4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1U -+ ECxMJRENvbVN1YkNBMS8wLQYDVQQDEyZNaWNyb1NvZnQgVGhyZWUgWWVhciBFbmNyeXB0aW9uIFBv -+ bGljeTCBoTASDAxWZXJpZmljYXRpb24CAgDqMIGKMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50c -+ nVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1Yk -+ NBMTEwLwYDVQQDEyhNaWNyb1NvZnQgVGhyZWUgWWVhciBWZXJpZmljYXRpb24gUG9saWN5MD4wEgw -+ NbXNfdnBuX3NlcnZlcgIBIDAoMBEwDwwKRW5jcnlwdGlvbgIBODATMBEMDFZlcmlmaWNhdGlvbgIB -+ OTCBmDAPDApzc2xfZGV2aWNlAgFzMIGEMIGBMAkMA3NzbAICAMswdDELMAkGA1UEBhMCVVMxEDAOB -+ gNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBA -+ sTCURDb21TdWJDQTEbMBkGA1UEAxMSU1NMIEludGVyb3AgUG9saWN5MIIBQDAXDBJzc2xfZGV2aWN -+ lX2ludGVyb3ACAXQwggEjMIGQMAoMBHNzbDECAgDMMIGBMQswCQYDVQQGEwJVUzEQMA4GA1UEChMH -+ RW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvb -+ VN1YkNBMSgwJgYDVQQDEx9TU0wgSW50ZXJvcCBWZXJpZmljYXRpb24gUG9saWN5MIGNMAoMBHNzbD -+ ICAgDNMH8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F -+ 0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExJjAkBgNVBAMTHVNTTCBJbnRlcm9w -+ IEVuY3J5cHRpb24gUG9saWN5MEMwFwwSdnBuX2NsaWVudF9tYWNoaW5lAgEhMCgwETAPDApFbmNye -+ XB0aW9uAgE6MBMwEQwMVmVyaWZpY2F0aW9uAgE7MIGiMBQMD3Zwbl9jbGllbnRfdXNlcgIBGTCBiT -+ CBhjAPDApEdWFsIFVzYWdlAgEvMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAY -+ DVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExGjAYBgNV -+ BAMTEUR1YWwgVXNhZ2UgUG9saWN5MDgwDAwHdnBuX2RpcgIBCjAoMBEwDwwKRW5jcnlwdGlvbgIBD -+ zATMBEMDFZlcmlmaWNhdGlvbgIBEDA6MA4MCXZwbl9ub2RpcgIBCzAoMBEwDwwKRW5jcnlwdGlvbg -+ IBETATMBEMDFZlcmlmaWNhdGlvbgIBEjA6MA4MCXdlYl9hZF9kYwIBHzAoMBEwDwwKRW5jcnlwdGl -+ vbgIBNjATMBEMDFZlcmlmaWNhdGlvbgIBNzA/MBMMDndlYl9hZF9kY19jbHMxAgFDMCgwETAPDApF -+ bmNyeXB0aW9uAgFvMBMwEQwMVmVyaWZpY2F0aW9uAgFwMD8wEwwOd2ViX2FkX2RjX2NsczICAUQwK -+ DARMA8MCkVuY3J5cHRpb24CAXEwEzARDAxWZXJpZmljYXRpb24CAXIwggE+MBAMC3dlYl9hZF9zdn -+ IyAgFhMIIBKDCBjzAQDApFbmNyeXB0aW9uAgIAsTB7MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW5 -+ 0cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1 -+ YkNBMSIwIAYDVQQDExlDTFMgMnlyIEVuY3J5cHRpb24gUG9saWN5MIGTMBIMDFZlcmlmaWNhdGlvb -+ gICALIwfTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYX -+ Rpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEkMCIGA1UEAxMbQ0xTIDJ5ciBWZXJ -+ pZmljYXRpb24gUG9saWN5MIIBLjAQDAt3ZWJfYWRfc3ZyMwIBYjCCARgwgYcwEAwKRW5jcnlwdGlv -+ bgICALMwczELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljY -+ XRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTEaMBgGA1UEAxMRRW5jcnlwdGlvbi -+ BQb2xpY3kwgYswEgwMVmVyaWZpY2F0aW9uAgIAtDB1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW5 -+ 0cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1 -+ YkNBMRwwGgYDVQQDExNWZXJpZmljYXRpb24gUG9saWN5MD8wEwwOd2ViX2FpX2Ntc19jbGkCAT4wK -+ DARMA8MCkVuY3J5cHRpb24CAWUwEzARDAxWZXJpZmljYXRpb24CAWYwPjASDA13ZWJfYWlfY21zX2 -+ RzAgE/MCgwETAPDApFbmNyeXB0aW9uAgFnMBMwEQwMVmVyaWZpY2F0aW9uAgFoMD8wEwwOd2ViX2F -+ pX2Ntc19zdnICAT0wKDARMA8MCkVuY3J5cHRpb24CAWMwEzARDAxWZXJpZmljYXRpb24CAWQwPDAO -+ DAl3ZWJfYmFzaWMCAWswKjASMBAMCkVuY3J5cHRpb24CAgC+MBQwEgwMVmVyaWZpY2F0aW9uAgIAv -+ zBCMBQMDndlYl9jbGlzdnJfZXhwAgIAgjAqMBIwEAwKRW5jcnlwdGlvbgICAOQwFDASDAxWZXJpZm -+ ljYXRpb24CAgDlMDkwDQwId2ViX2NsczECAUUwKDARMA8MCkVuY3J5cHRpb24CAXMwEzARDAxWZXJ -+ pZmljYXRpb24CAXQwOTANDAh3ZWJfY2xzMgIBRjAoMBEwDwwKRW5jcnlwdGlvbgIBdTATMBEMDFZl -+ cmlmaWNhdGlvbgIBdjA+MBIMDXdlYl9jbXNjbGllbnQCAUEwKDARMA8MCkVuY3J5cHRpb24CAWswE -+ zARDAxWZXJpZmljYXRpb24CAWwwRDAXDBJ3ZWJfY21zY2xpZW50X2NsczECAUswKTARMA8MCkVuY3 -+ J5cHRpb24CAX8wFDASDAxWZXJpZmljYXRpb24CAgCAMEUwFwwSd2ViX2Ntc2NsaWVudF9jbHMyAgF -+ MMCowEjAQDApFbmNyeXB0aW9uAgIAgTAUMBIMDFZlcmlmaWNhdGlvbgICAIIwPjASDA13ZWJfY21z -+ c2VydmVyAgFCMCgwETAPDApFbmNyeXB0aW9uAgFtMBMwEQwMVmVyaWZpY2F0aW9uAgFuMEUwFwwSd -+ 2ViX2Ntc3NlcnZlcl9jbHMxAgFNMCowEjAQDApFbmNyeXB0aW9uAgIAgzAUMBIMDFZlcmlmaWNhdG -+ lvbgICAIQwRTAXDBJ3ZWJfY21zc2VydmVyX2NsczICAU4wKjASMBAMCkVuY3J5cHRpb24CAgCFMBQ -+ wEgwMVmVyaWZpY2F0aW9uAgIAhjA9MBEMDHdlYl9jb2Rlc2lnbgIBHjAoMBEwDwwKRW5jcnlwdGlv -+ bgIBNDATMBEMDFZlcmlmaWNhdGlvbgIBNTBCMBYMEXdlYl9jb2Rlc2lnbl9jbHMxAgFJMCgwETAPD -+ ApFbmNyeXB0aW9uAgF7MBMwEQwMVmVyaWZpY2F0aW9uAgF8MEIwFgwRd2ViX2NvZGVzaWduX2Nscz -+ ICAUowKDARMA8MCkVuY3J5cHRpb24CAX0wEzARDAxWZXJpZmljYXRpb24CAX4wggEsMBAMC3dlYl9 -+ kZWZhdWx0AgEcMIIBFjCBhjAPDApFbmNyeXB0aW9uAgEwMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQK -+ EwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ -+ 29tU3ViQ0ExGjAYBgNVBAMTEUVuY3J5cHRpb24gUG9saWN5MIGKMBEMDFZlcmlmaWNhdGlvbgIBMT -+ B1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiB -+ BdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRwwGgYDVQQDExNWZXJpZmljYXRpb24gUG9s -+ aWN5MCwwEwwOd2ViX29uZWtleXBhaXICATwwFTATMBEMDFZlcmlmaWNhdGlvbgIBYjA7MA8MCndlY -+ l9zZXJ2ZXICAR0wKDARMA8MCkVuY3J5cHRpb24CATIwEzARDAxWZXJpZmljYXRpb24CATMwKjAQDA -+ t3ZWJfc2VydmVyMgIBdTAWMBQwEgwMVmVyaWZpY2F0aW9uAgIAzjBEMBYMEHdlYl9zZXJ2ZXJfYmF -+ zaWMCAgCDMCowEjAQDApFbmNyeXB0aW9uAgIA5jAUMBIMDFZlcmlmaWNhdGlvbgICAOcwQDAUDA93 -+ ZWJfc2VydmVyX2NsczECAUcwKDARMA8MCkVuY3J5cHRpb24CAXcwEzARDAxWZXJpZmljYXRpb24CA -+ XgwggFAMBQMD3dlYl9zZXJ2ZXJfY2xzMgIBSDCCASYwgY4wDwwKRW5jcnlwdGlvbgIBeTB7MQswCQ -+ YDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3J -+ pdGllczESMBAGA1UECxMJRENvbVN1YkNBMSIwIAYDVQQDExlDTFMgMnlyIEVuY3J5cHRpb24gUG9s -+ aWN5MIGSMBEMDFZlcmlmaWNhdGlvbgIBejB9MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzd -+ DEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMS -+ QwIgYDVQQDExtDTFMgMnlyIFZlcmlmaWNhdGlvbiBQb2xpY3kwggEyMBQMD3dlYl9zZXJ2ZXJfY2x -+ zMwIBYDCCARgwgYcwEAwKRW5jcnlwdGlvbgICAK8wczELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0Vu -+ dHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21Td -+ WJDQTEaMBgGA1UEAxMRRW5jcnlwdGlvbiBQb2xpY3kwgYswEgwMVmVyaWZpY2F0aW9uAgIAsDB1MQ -+ swCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXR -+ ob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBMRwwGgYDVQQDExNWZXJpZmljYXRpb24gUG9saWN5 -+ MIIBQjAUDA93ZWJfc2VydmVyX2NsczQCAV8wggEoMIGPMBAMCkVuY3J5cHRpb24CAgCtMHsxCzAJB -+ gNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcm -+ l0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0ExIjAgBgNVBAMTGUNMUyA0eXIgRW5jcnlwdGlvbiBQb2x -+ pY3kwgZMwEgwMVmVyaWZpY2F0aW9uAgIArjB9MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVz -+ dDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczESMBAGA1UECxMJRENvbVN1YkNBM -+ SQwIgYDVQQDExtDTFMgNHlyIFZlcmlmaWNhdGlvbiBQb2xpY3kwRjAYDBN3ZWJfc2VydmVyX2V4cG -+ VyaWFuAgFuMCowEjAQDApFbmNyeXB0aW9uAgIAwzAUMBIMDFZlcmlmaWNhdGlvbgICAMQwQDAUDA9 -+ 3ZWJfc2VydmVyX2hpZ2gCATswKDARMA8MCkVuY3J5cHRpb24CAWAwEzARDAxWZXJpZmljYXRpb24C -+ AWEwGwYJKoZIhvZ9B000MQ4wDAYKKoZIhvZ9B001ATAhMB8GA1UdIwQYMBaAFDy++9gIa1JL8T+Oh -+ 9HW5F160lV9MA0GCSqGSIb3DQEBBQUAA4IBAQBelvaP82tFhjcHOTSDP97QLcqo2yE9RjjLtC/In8 -+ u/Zi/8y6jR9GRE11U6GbF+5+EJ5pckTMJ8Oorn3ZVOl4dKyzTN9m2rLjdUXNWd/th8Ja1RD/9hpMD -+ o5HUUYJEoOQxufTZnWfEZ2AISB7rXLCFZpdHGvc3H2ORtkhV+SuTmLpNkN1Zsbv8TXNi4szuX5sbA -+ y/mX7G8q0Twbb+GGpZjlKV226xc2Ejy3uYGrUK0kEr6u/ONTK1844vsuZPkcJOMcj7/c4o8oKKVMT -+ Fyafl1swsxHWn6MTh6WqI5k2LBcyEZSptDcG1brE7BU1JAOE9F7nkaoOOWefJs3n7B8piLg -+crossCertificatePair;binary:: MIIGUqCCBk4wggZKMIIFMqADAgECAgRIwMPgMA0GCSqGSIb3 -+ DQEBBQUAMFgxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY -+ 2F0aW9uIEF1dGhvcml0aWVzMRMwEQYDVQQLEwpEQ29tUm9vdENBMB4XDTEwMDQyMDE0NDQwNloXDT -+ MwMDMyMDE1MTQwNlowVzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUN -+ lcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTCCASIwDQYJKoZIhvcN -+ AQEBBQADggEPADCCAQoCggEBAOMj486WAJ+GC3aOTn7g1p3+tzHJ8YUAoLW0y4WC6eleA+Yq9M+FP -+ Xlo+E6AMak4+HENfQMBa5bUgqJMGL20ZOktm0jpMtGtbS/J6Y9TrujpysVnO4SZwuWJOlwV+DLfgH -+ JYFcE/oeVej/TcoQw+zV0RkeDVA4npgOw5FWKzPlnKANF8KN598KK92jx+p60egFYyIY04MknO/cH -+ APZXT7tVIp1ljyHyNwMPWiwYdyVdR7IkrFQrb55lHEj4/KdHoLISe4/sQB1Yw6S9fz+A7HhF3BBkb -+ tNJk+jfjDL2/hNq0VP9b9zURJKSGEUTBaoAbvcWw7p7v2t7VOTB5Wb496SECAwEAAaOCAxswggMXM -+ A4GA1UdDwEB/wQEAwIBBjA8BgNVHSAENTAzMA8GDWCGSAGG+muBSAMKAgEwDwYNYIZIAYb6a4FIAw -+ oCAjAPBg1ghkgBhvprgUgDCgIDMA8GA1UdEwEB/wQFMAMBAf8wggEBBggrBgEFBQcBAQSB9DCB8TC -+ BnQYIKwYBBQUHMAKGgZBsZGFwOi8vZGNvbWRpcjEubWFuYWdlZC5lbnRydXN0LmNvbS9vdT1EQ29t -+ Um9vdENBLG91PUNlcnRpZmljYXRpb24lMjBBdXRob3JpdGllcyxvPUVudHJ1c3QsYz1VUz9jQUNlc -+ nRpZmljYXRlO2JpbmFyeSxjcm9zc0NlcnRpZmljYXRlUGFpcjtiaW5hcnkwTwYIKwYBBQUHMAKGQ2 -+ h0dHA6Ly9kY29td2ViMS5tYW5hZ2VkLmVudHJ1c3QuY29tL0FJQS9DZXJ0c0lzc3VlZFRvRENvbVJ -+ vb3RDQS5wN2MwggFUBgNVHR8EggFLMIIBRzCB06CB0KCBzYY4aHR0cDovL2Rjb213ZWIxLm1hbmFn -+ ZWQuZW50cnVzdC5jb20vQ1JMcy9EQ29tUm9vdENBMS5jcmyGgZBsZGFwOi8vZGNvbWRpcjEubWFuY -+ WdlZC5lbnRydXN0LmNvbS9jbj1XaW5Db21iaW5lZDEsb3U9RENvbVJvb3RDQSxvdT1DZXJ0aWZpY2 -+ F0aW9uJTIwQXV0aG9yaXRpZXMsbz1FbnRydXN0LGM9VVM/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGl -+ zdDtiaW5hcnkwb6BtoGukaTBnMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UE -+ CxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczETMBEGA1UECxMKRENvbVJvb3RDQTENMAsGA1UEA -+ xMEQ1JMMTAfBgNVHSMEGDAWgBRFx/xyHQhRD4vvL4V0iTRGDDP/JTAdBgNVHQ4EFgQUPL772AhrUk -+ vxP46H0dbkXXrSVX0wGQYJKoZIhvZ9B0EABAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADggE -+ BAJQrdloQCgTe0ahJyTU/fsKLzYXVGJOwnrwyof/+7emUfZS/OhKYuCfQ9w/wWLhT5SUzm9GDlUfk -+ YUfpL+/5joymDJO8/thcEq/k2PJepSFf7IMY8635kNz27kI9fA8JQGn7nEI8WBjX26qs7Ho7QKVkv -+ 6YEDuGeJwBLTGyNerDEf5n+DdMvrDmVAOs62T8uTZDb9gn/uIEGv3vaR+rs3KxvDhEr/2OFJtDWHw -+ PdHFOrr1pNkNWqdStwoE2/fxUfccQhLn+H5GgKLD7YT74uUCi+VFP1juV3F7jUlytgtMnnbqRIbDn -+ 4bMPn2HOmxdQ20amsdKX4bfosqFMepfSxWRQ= -+crossCertificatePair;binary:: MIIGQaCCBj0wggY5MIIFIaADAgECAgRIwJY0MA0GCSqGSIb3 -+ DQEBBQUAMFgxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY -+ 2F0aW9uIEF1dGhvcml0aWVzMRMwEQYDVQQLEwpEQ29tUm9vdENBMB4XDTA4MDkwNTE4MDQxMVoXDT -+ E4MDkwNTAyMTMzN1owVzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUN -+ lcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQTCCASIwDQYJKoZIhvcN -+ AQEBBQADggEPADCCAQoCggEBAL+MSY0GXRSMIIm5l+bMpXvk8rlG/Rjqaw0TNZ2w+KsG6ktNWXDll -+ A1i1l0Fvx2qj4O/z5bNfgmUmJZFamyWOS6TkwX2C+2DspI7P3a+gVTVu+7VJkevo3Hye2Pd6bAf/+ -+ bfV2IhSyAOe0wW0sANyQrIjzsU1r6YBjpcT1E5QZdnzSrEYRoBhJGXf8/v+Zu21AqOZ9EpagpvmsZ -+ 4UI8ORFg2PV0UOmnwNkMVO21JH1sUGYfKP9JAoO8vTzgwYbDN1w5DMC7SqWBl00OF6pGGaglJ5D16 -+ OcopR8aZVePxj+dW+MADgEufai5CqhUKZ6CA1pa+P6c1lPcFEGgz9AQS420CAwEAAaOCAwowggMGM -+ A4GA1UdDwEB/wQEAwIBBjA8BgNVHSAENTAzMA8GDWCGSAGG+muBSAMKAgEwDwYNYIZIAYb6a4FIAw -+ oCAjAPBg1ghkgBhvprgUgDCgIDMA8GA1UdEwEB/wQFMAMBAf8wggEBBggrBgEFBQcBAQSB9DCB8TC -+ BnQYIKwYBBQUHMAKGgZBsZGFwOi8vZGNvbWRpcjEubWFuYWdlZC5lbnRydXN0LmNvbS9vdT1EQ29t -+ Um9vdENBLG91PUNlcnRpZmljYXRpb24lMjBBdXRob3JpdGllcyxvPUVudHJ1c3QsYz1VUz9jQUNlc -+ nRpZmljYXRlO2JpbmFyeSxjcm9zc0NlcnRpZmljYXRlUGFpcjtiaW5hcnkwTwYIKwYBBQUHMAKGQ2 -+ h0dHA6Ly9kY29td2ViMS5tYW5hZ2VkLmVudHJ1c3QuY29tL0FJQS9DZXJ0c0lzc3VlZFRvRENvbVJ -+ vb3RDQS5wN2MwggFDBgNVHR8EggE6MIIBNjCBwqCBv6CBvIaBgGxkYXA6Ly9kY29tZGlyMS5tYW5h -+ Z2VkLmVudHJ1c3QuY29tL291PURDb21Sb290Q0Esb3U9Q2VydGlmaWNhdGlvbiUyMEF1dGhvcml0a -+ WVzLG89RW50cnVzdCxjPVVTP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5hjdodHRwOi -+ 8vZGNvbXdlYjEubWFuYWdlZC5lbnRydXN0LmNvbS9DUkxzL0RDb21Sb290Q0EuY3JsMG+gbaBrpGk -+ wZzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24g -+ QXV0aG9yaXRpZXMxEzARBgNVBAsTCkRDb21Sb290Q0ExDTALBgNVBAMTBENSTDEwHwYDVR0jBBgwF -+ oAUh1mBY1JFXsCw39HI6bl1OBAu3tkwHQYDVR0OBBYEFPQWLgG7q5AZpChCDZ3AH5yvEIYrMBkGCS -+ qGSIb2fQdBAAQMMAobBFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4IBAQCrafi2DFqdhpXtzeJpUgZ -+ glNOwZUBOp5thJUH7+yMcgl5Ka4JIqqNpw3ZbFPFT9Ni4IzDmJYyPgqHmgRubxFWpAHdP8SjEK7pl -+ 6DwDmbCAWBiq7SmSfqt502FUUyiTcZsCLi6GqE4fetej41t3NaGidqyVQXPJ26Ti2jNT4NzRnADi6 -+ vOzMzxMSkWH1OaHoGLtTVpIjkbJZygnSmof4+gs4M1fmH4FVTcWV6t8zbTwkH4RTYSHVX04aM4ZBp -+ nhMq6sk9uNL+qndpWkO7u7zr6K527kl6/t1Xr9/vnzD0ACVk/gluI7MvCUIzP55o01Rp90ZCMIMak -+ u0qrESgh0GXln -+cACertificate;binary:: MIIGSjCCBTKgAwIBAgIESMDD4DANBgkqhkiG9w0BAQUFADBYMQswCQY -+ DVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3Jp -+ dGllczETMBEGA1UECxMKRENvbVJvb3RDQTAeFw0xMDA0MjAxNDQ0MDZaFw0zMDAzMjAxNTE0MDZaM -+ FcxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIE -+ F1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggE -+ KAoIBAQDjI+POlgCfhgt2jk5+4Nad/rcxyfGFAKC1tMuFgunpXgPmKvTPhT15aPhOgDGpOPhxDX0D -+ AWuW1IKiTBi9tGTpLZtI6TLRrW0vyemPU67o6crFZzuEmcLliTpcFfgy34ByWBXBP6HlXo/03KEMP -+ s1dEZHg1QOJ6YDsORVisz5ZygDRfCjeffCivdo8fqetHoBWMiGNODJJzv3BwD2V0+7VSKdZY8h8jc -+ DD1osGHclXUeyJKxUK2+eZRxI+PynR6CyEnuP7EAdWMOkvX8/gOx4RdwQZG7TSZPo34wy9v4TatFT -+ /W/c1ESSkhhFEwWqAG73FsO6e79re1TkweVm+PekhAgMBAAGjggMbMIIDFzAOBgNVHQ8BAf8EBAMC -+ AQYwPAYDVR0gBDUwMzAPBg1ghkgBhvprgUgDCgIBMA8GDWCGSAGG+muBSAMKAgIwDwYNYIZIAYb6a -+ 4FIAwoCAzAPBgNVHRMBAf8EBTADAQH/MIIBAQYIKwYBBQUHAQEEgfQwgfEwgZ0GCCsGAQUFBzACho -+ GQbGRhcDovL2Rjb21kaXIxLm1hbmFnZWQuZW50cnVzdC5jb20vb3U9RENvbVJvb3RDQSxvdT1DZXJ -+ 0aWZpY2F0aW9uJTIwQXV0aG9yaXRpZXMsbz1FbnRydXN0LGM9VVM/Y0FDZXJ0aWZpY2F0ZTtiaW5h -+ cnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5ME8GCCsGAQUFBzAChkNodHRwOi8vZGNvbXdlY -+ jEubWFuYWdlZC5lbnRydXN0LmNvbS9BSUEvQ2VydHNJc3N1ZWRUb0RDb21Sb290Q0EucDdjMIIBVA -+ YDVR0fBIIBSzCCAUcwgdOggdCggc2GOGh0dHA6Ly9kY29td2ViMS5tYW5hZ2VkLmVudHJ1c3QuY29 -+ tL0NSTHMvRENvbVJvb3RDQTEuY3JshoGQbGRhcDovL2Rjb21kaXIxLm1hbmFnZWQuZW50cnVzdC5j -+ b20vY249V2luQ29tYmluZWQxLG91PURDb21Sb290Q0Esb3U9Q2VydGlmaWNhdGlvbiUyMEF1dGhvc -+ ml0aWVzLG89RW50cnVzdCxjPVVTP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5MG+gba -+ BrpGkwZzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXR -+ pb24gQXV0aG9yaXRpZXMxEzARBgNVBAsTCkRDb21Sb290Q0ExDTALBgNVBAMTBENSTDEwHwYDVR0j -+ BBgwFoAURcf8ch0IUQ+L7y+FdIk0Rgwz/yUwHQYDVR0OBBYEFDy++9gIa1JL8T+Oh9HW5F160lV9M -+ BkGCSqGSIb2fQdBAAQMMAobBFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4IBAQCUK3ZaEAoE3tGoSc -+ k1P37Ci82F1RiTsJ68MqH//u3plH2UvzoSmLgn0PcP8Fi4U+UlM5vRg5VH5GFH6S/v+Y6MpgyTvP7 -+ YXBKv5NjyXqUhX+yDGPOt+ZDc9u5CPXwPCUBp+5xCPFgY19uqrOx6O0ClZL+mBA7hnicAS0xsjXqw -+ xH+Z/g3TL6w5lQDrOtk/Lk2Q2/YJ/7iBBr972kfq7Nysbw4RK/9jhSbQ1h8D3RxTq69aTZDVqnUrc -+ KBNv38VH3HEIS5/h+RoCiw+2E++LlAovlRT9Y7ldxe41JcrYLTJ526kSGw5+GzD59hzpsXUNtGprH -+ Sl+G36LKhTHqX0sVkU -+cACertificate;binary:: MIIGOTCCBSGgAwIBAgIESMCWNDANBgkqhkiG9w0BAQUFADBYMQswCQY -+ DVQQGEwJVUzEQMA4GA1UEChMHRW50cnVzdDEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3Jp -+ dGllczETMBEGA1UECxMKRENvbVJvb3RDQTAeFw0wODA5MDUxODA0MTFaFw0xODA5MDUwMjEzMzdaM -+ FcxCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIE -+ F1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ29tU3ViQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggE -+ KAoIBAQC/jEmNBl0UjCCJuZfmzKV75PK5Rv0Y6msNEzWdsPirBupLTVlw5ZQNYtZdBb8dqo+Dv8+W -+ zX4JlJiWRWpsljkuk5MF9gvtg7KSOz92voFU1bvu1SZHr6Nx8ntj3emwH//m31diIUsgDntMFtLAD -+ ckKyI87FNa+mAY6XE9ROUGXZ80qxGEaAYSRl3/P7/mbttQKjmfRKWoKb5rGeFCPDkRYNj1dFDpp8D -+ ZDFTttSR9bFBmHyj/SQKDvL084MGGwzdcOQzAu0qlgZdNDheqRhmoJSeQ9ejnKKUfGmVXj8Y/nVvj -+ AA4BLn2ouQqoVCmeggNaWvj+nNZT3BRBoM/QEEuNtAgMBAAGjggMKMIIDBjAOBgNVHQ8BAf8EBAMC -+ AQYwPAYDVR0gBDUwMzAPBg1ghkgBhvprgUgDCgIBMA8GDWCGSAGG+muBSAMKAgIwDwYNYIZIAYb6a -+ 4FIAwoCAzAPBgNVHRMBAf8EBTADAQH/MIIBAQYIKwYBBQUHAQEEgfQwgfEwgZ0GCCsGAQUFBzACho -+ GQbGRhcDovL2Rjb21kaXIxLm1hbmFnZWQuZW50cnVzdC5jb20vb3U9RENvbVJvb3RDQSxvdT1DZXJ -+ 0aWZpY2F0aW9uJTIwQXV0aG9yaXRpZXMsbz1FbnRydXN0LGM9VVM/Y0FDZXJ0aWZpY2F0ZTtiaW5h -+ cnksY3Jvc3NDZXJ0aWZpY2F0ZVBhaXI7YmluYXJ5ME8GCCsGAQUFBzAChkNodHRwOi8vZGNvbXdlY -+ jEubWFuYWdlZC5lbnRydXN0LmNvbS9BSUEvQ2VydHNJc3N1ZWRUb0RDb21Sb290Q0EucDdjMIIBQw -+ YDVR0fBIIBOjCCATYwgcKggb+ggbyGgYBsZGFwOi8vZGNvbWRpcjEubWFuYWdlZC5lbnRydXN0LmN -+ vbS9vdT1EQ29tUm9vdENBLG91PUNlcnRpZmljYXRpb24lMjBBdXRob3JpdGllcyxvPUVudHJ1c3Qs -+ Yz1VUz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeYY3aHR0cDovL2Rjb213ZWIxLm1hb -+ mFnZWQuZW50cnVzdC5jb20vQ1JMcy9EQ29tUm9vdENBLmNybDBvoG2ga6RpMGcxCzAJBgNVBAYTAl -+ VTMRAwDgYDVQQKEwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRM -+ wEQYDVQQLEwpEQ29tUm9vdENBMQ0wCwYDVQQDEwRDUkwxMB8GA1UdIwQYMBaAFIdZgWNSRV7AsN/R -+ yOm5dTgQLt7ZMB0GA1UdDgQWBBT0Fi4Bu6uQGaQoQg2dwB+crxCGKzAZBgkqhkiG9n0HQQAEDDAKG -+ wRWNy4xAwIAgTANBgkqhkiG9w0BAQUFAAOCAQEAq2n4tgxanYaV7c3iaVIGYJTTsGVATqebYSVB+/ -+ sjHIJeSmuCSKqjacN2WxTxU/TYuCMw5iWMj4Kh5oEbm8RVqQB3T/EoxCu6Zeg8A5mwgFgYqu0pkn6 -+ redNhVFMok3GbAi4uhqhOH3rXo+NbdzWhonaslUFzyduk4tozU+Dc0ZwA4urzszM8TEpFh9Tmh6Bi -+ 7U1aSI5GyWcoJ0pqH+PoLODNX5h+BVU3FlerfM208JB+EU2Eh1V9OGjOGQaZ4TKurJPbjS/qp3aVp -+ Du7u86+iudu5Jev7dV6/f758w9AAlZP4JbiOzLwlCMz+eaNNUafdGQjCDGpLtKqxEoIdBl5Zw== -+objectClass: organizationalUnit -+objectClass: top -+objectClass: extensibleobject -+ou: binary -+nsUniqueId: f49ca103-c2ee11e7-9170b029-e68fda34 -+creatorsName: -+modifiersName: -+createTimestamp: 20171106123544Z -+modifyTimestamp: 20171106123544Z -+ -+# entry-id: 3 -+dn: cn=test,ou=binary,dc=example,dc=com -+userCertificate:: MIIGfzCCBWcCAQEwgYOhgYAwfqR8MHoxCzAJBgNVBAYTAlVTMRAwDgYDVQQK -+ EwdFbnRydXN0MSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRIwEAYDVQQLEwlEQ -+ 29tU3ViQ0ExITAfBgNVBAMTGFNQT0MgU2VydmVyIExvZ2luIFBvbGljeTBnoGUwYzBbpFkwVzELMA -+ kGA1UEBhMCVVMxEDAOBgNVBAoTB0VudHJ1c3QxIjAgBgNVBAsTGUNlcnRpZmljYXRpb24gQXV0aG9 -+ yaXRpZXMxEjAQBgNVBAsTCURDb21TdWJDQQIESMDD4DANBgkqhkiG9w0BAQUFAAIEV4eo1TAiGA8y -+ MDE3MTAxNTIyNDYwOVoYDzIwMTcxMTE0MjI0NjA5WjCCBBUwHwYJKoZIhvZ9B00BMRIwEAIBAAIBC -+ AIBCAIBCgMCAGkwFAYJKoZIhvZ9B00DMQcwBQwDQUxMMBEGCSqGSIb2fQdNBTEEAwID2DAPBgkqhk -+ iG9n0HTQYxAgwAMBcGCSqGSIb2fQdNCTEKDAhSU0EtMjA0ODApBgkqhkiG9n0HTQ4xHDAaDAlwcml -+ udGFibGUMB3RlbGV0ZXgMBHV0ZjgwEQYJKoZIhvZ9B00PMQQDAgeAMBEGCSqGSIb2fQdNFTEEAwIH -+ gDAQBgkqhkiG9n0HTRYxAwMBADAQBgkqhkiG9n0HTQgxAwMBADAQBgkqhkiG9n0HTSwxAwMBADAPB -+ gkqhkiG9n0HTQsxAjAAMBAGCSqGSIb2fQdNDDEDAwEAMBAGCSqGSIb2fQdNDTEDAgEeMA8GCSqGSI -+ b2fQdNEzECDAAwEAYJKoZIhvZ9B00XMQMBAQAwEQYJKoZIhvZ9B00YMQQCAgfQMBAGCSqGSIb2fQd -+ NHzEDAQEAMBAGCSqGSIb2fQdNJjEDAwEAMBAGCSqGSIb2fQdNGTEDAgECMBAGCSqGSIb2fQdNGzED -+ AQEAMBAGCSqGSIb2fQdNKTEDAQEAMBAGCSqGSIb2fQdNHDEDAgEAMBAGCSqGSIb2fQdNHTEDAgEBM -+ BAGCSqGSIb2fQdNIDEDAwEAMBEGCSqGSIb2fQdNITEEAwIE8DAPBgkqhkiG9n0HTSMxAgwAMA8GCS -+ qGSIb2fQdNJDECDAAwJAYJKoZIhvZ9B00lMRcwFQwJRGlyZWN0b3J5DANFQUIMA0dBTDAQBgkqhki -+ G9n0HTSsxAwMBADAPBgkqhkiG9n0HTTYxAgwAMBEGCSqGSIb2fQdNMzEEAwIHgDAPBgkqhkiG9n0H -+ TScxAgwAMBAGCSqGSIb2fQdNETEDAgECMBAGCSqGSIb2fQdNKDEDAgFkMBEGCiqGSIb2fQdNLQExA -+ wIBAzBEBgoqhkiG9n0HTS0CMTYwNAwMZW50ZWxsaWdlbmNlDAZkaXJlY3QMCHpmLWxvY2FsDAp6Zi -+ 1yb2FtaW5nDAZ6Zi1tc2YwFwYKKoZIhvZ9B00tAzEJDAdleGVjdXRlMBAGCSqGSIb2fQdNMTEDAQE -+ AMBAGCSqGSIb2fQdNMjEDAQEAMBAGCSqGSIb2fQdNOTEDAQH/MA8GCSqGSIb2fQdNLzECDAAwEAYJ -+ KoZIhvZ9B004MQMBAQAwEwYJKoZIhvZ9B003MQYMBENBU1QwEAYJKoZIhvZ9B007MQMBAQAwFgYJK -+ oZIhvZ9B009MQkMB0VudHJ1c3QwEAYJKoZIhvZ9B00+MQMBAQAwEAYJKoZIhvZ9B00/MQMBAQAwFw -+ YJKoZIhvZ9B00KMQoMCFJTQS0yMDQ4MBAGCSqGSIb2fQdNQzEDAQEAMCEwHwYDVR0jBBgwFoAUPL7 -+ 72AhrUkvxP46H0dbkXXrSVX0wDQYJKoZIhvcNAQEFBQADggEBADrezRWX0fuPC415BUa3tafMLaVO -+ 24v3CP+qYud4Z6IKI7jNtt2pcneaYjQ7iaxypE3N7Wwlim6Ak4yuwwJ9SrKOSe7YPiFOuugvNy2fk -+ +f2h3bFkLm40bkjPPH8bih4sLyU8RcN2cAJLxHINwXO3ALKBo3IdxrfcoKquO7g+R4+ZPvmS/95J9 -+ aQ08FZKpkv+ORPRZySkr0zMUARdBBguklHqFeczn5tQnmJcsfVlP4DC7IPqw2xM8l3b+iAH5pyqgb -+ o/Lk11VWkD11s3K8/Bf40eH23upDOwmYBAszHdXU4+5HNZ/An6xfVEjr/+KxUAEVD5TGQMVJY6SCS -+ zN3ONRc= -+objectClass: top -+objectClass: extensibleobject -+cn: test -+nsUniqueId: f49ca104-c2ee11e7-9170b029-e68fda34 -+creatorsName: -+modifiersName: -+createTimestamp: 20171106123544Z -+modifyTimestamp: 20171106123544Z -+ -diff --git a/dirsrvtests/tests/tickets/ticket49441_test.py b/dirsrvtests/tests/tickets/ticket49441_test.py -new file mode 100644 -index 000000000..e50ebc128 ---- /dev/null -+++ b/dirsrvtests/tests/tickets/ticket49441_test.py -@@ -0,0 +1,74 @@ -+import logging -+import pytest -+import os -+import ldap -+from lib389._constants import * -+from lib389.topologies import topology_st as topo -+from lib389.utils import * -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+ -+def test_ticket49441(topo): -+ """Import ldif with large indexed binary attributes, the server should not -+ crash -+ -+ :id: 4e5df145-cbd1-4955-8f77-6a7eaa14beba -+ :setup: standalone topology -+ :steps: -+ 1. Add indexes for binary attributes -+ 2. Perform online import -+ 3. Verify server is still running -+ :expectedresults: -+ 1. Indexes are successfully added -+ 2. Import succeeds -+ 3. Server is still running -+ """ -+ -+ log.info('Position ldif files, and add indexes...') -+ ldif_dir = topo.standalone.get_ldif_dir() + "binary.ldif" -+ ldif_file = (topo.standalone.getDir(__file__, DATA_DIR) + -+ "ticket49441/binary.ldif") -+ shutil.copyfile(ldif_file, ldif_dir) -+ args = {INDEX_TYPE: ['eq', 'pres']} -+ for attr in ('usercertificate', 'authorityrevocationlist', -+ 'certificaterevocationlist', 'crosscertificatepair', -+ 'cacertificate'): -+ try: -+ topo.standalone.index.create(suffix=DEFAULT_SUFFIX, -+ be_name='userroot', -+ attr=attr, args=args) -+ except ldap.LDAPError as e: -+ log.fatal("Failed to add index '{}' error: {}".format(attr, str(e))) -+ raise e -+ -+ log.info('Import LDIF with large indexed binary attributes...') -+ try: -+ topo.standalone.tasks.importLDIF(suffix=DEFAULT_SUFFIX, -+ input_file=ldif_dir, -+ args={TASK_WAIT: True}) -+ except: -+ log.fatal('Import failed!') -+ assert False -+ -+ log.info('Verify server is still running...') -+ try: -+ topo.standalone.search_s("", ldap.SCOPE_BASE, "objectclass=*") -+ except ldap.LDAPError as e: -+ log.fatal('Server is not alive: ' + 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/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c -index 58b11ed99..a565db87b 100644 ---- a/ldap/servers/slapd/back-ldbm/index.c -+++ b/ldap/servers/slapd/back-ldbm/index.c -@@ -827,8 +827,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; -@@ -926,8 +928,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))) != NULL) { -@@ -1773,8 +1777,7 @@ 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]; - -@@ -1782,7 +1785,6 @@ addordel_values( - (flags & BE_INDEX_ADD) ? "add" : "del", - encoded (&key, encbuf)); - } --#endif - - if (NULL != txn) { - db_txn = txn->back_txn_txn; -@@ -1939,8 +1941,8 @@ 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]; - -@@ -1948,7 +1950,6 @@ addordel_values_sv( - (flags & BE_INDEX_ADD) ? "add" : "del", - encoded(&key, encbuf)); - } --#endif - - if (NULL != txn) { - db_txn = txn->back_txn_txn; --- -2.13.6 - diff --git a/SOURCES/0034-Ticket-48681-logconv.pl-fix-sasl-bind-stats.patch b/SOURCES/0034-Ticket-48681-logconv.pl-fix-sasl-bind-stats.patch new file mode 100644 index 0000000..9d63e57 --- /dev/null +++ b/SOURCES/0034-Ticket-48681-logconv.pl-fix-sasl-bind-stats.patch @@ -0,0 +1,41 @@ +From e9514af2fed9f882a8d11d509ffb99e49a304438 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0034-Ticket-49441-Import-crashes-oneline-fix.patch b/SOURCES/0034-Ticket-49441-Import-crashes-oneline-fix.patch deleted file mode 100644 index d9b84d3..0000000 --- a/SOURCES/0034-Ticket-49441-Import-crashes-oneline-fix.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2c868707b3ae1a4255ea33610b177f8a98f4a3f3 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Tue, 7 Nov 2017 17:09:18 +1000 -Subject: [PATCH] Ticket 49441 - Import crashes - oneline fix - -Bug Description: index.c fails to compile. - -Fix Description: Excess braces due to copy paste issue. - -https://pagure.io/389-ds-base/issue/49441 - -Author: wibrown - -Review by: oneline rule - -(cherry picked from commit be4d7e5a82c1616317fa52968d2814e3f922254c) ---- - ldap/servers/slapd/back-ldbm/index.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c -index a565db87b..587f4d991 100644 ---- a/ldap/servers/slapd/back-ldbm/index.c -+++ b/ldap/servers/slapd/back-ldbm/index.c -@@ -1778,7 +1778,6 @@ addordel_values( - key.flags = DB_DBT_USERMEM; - key.ulen = tmpbuflen; - if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) { -- { - char encbuf[BUFSIZ]; - - slapi_log_err(SLAPI_LOG_TRACE, "addordel_values", "%s_value(\"%s\")\n", -@@ -1943,7 +1942,6 @@ addordel_values_sv( - key.ulen = tmpbuflen; - - if (slapi_is_loglevel_set(LDAP_DEBUG_TRACE)) { -- { - char encbuf[BUFSIZ]; - - slapi_log_err(SLAPI_LOG_TRACE, "addordel_values_sv", "%s_value(\"%s\")\n", --- -2.13.6 - diff --git a/SOURCES/0035-Ticket-49241-Update-man-page-and-usage-for-db2bak.pl.patch b/SOURCES/0035-Ticket-49241-Update-man-page-and-usage-for-db2bak.pl.patch new file mode 100644 index 0000000..6cd8932 --- /dev/null +++ b/SOURCES/0035-Ticket-49241-Update-man-page-and-usage-for-db2bak.pl.patch @@ -0,0 +1,51 @@ +From cdcc387f6f1287da1edda418d746e6c2c772e5bd Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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-)\n"); +- print(STDERR " -a backupdir - Backup directory\n"); ++ print(STDERR " -A backupdir - Backup directory symlink(backupdir/ID-)\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 + diff --git a/SOURCES/0035-Ticket-49377-Incoming-BER-too-large-with-TLS-on-plai.patch b/SOURCES/0035-Ticket-49377-Incoming-BER-too-large-with-TLS-on-plai.patch deleted file mode 100644 index 6d7c5f4..0000000 --- a/SOURCES/0035-Ticket-49377-Incoming-BER-too-large-with-TLS-on-plai.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 40811ab7571ddf0a6905b3b019229bdb555bd04d Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Tue, 7 Nov 2017 12:42:11 +1000 -Subject: [PATCH] Ticket 49377 - Incoming BER too large with TLS on plain port - -Bug Description: When doing TLS to a plain port, a message of -"ber element 3 bytes too large for max ber" when max ber > 3. - -Fix Description: When ber_len < maxber, report that the request -may be misformed instead of "oversize" instead. This can lead -to a better diagnosis. - -https://pagure.io/389-ds-base/issue/49377 - -Author: wibrown - -Review by: mreynolds (thanks!) - -Cherry picked from commit b3629af054760d9421a41d63b8b8ed513bb6944d ---- - ldap/servers/slapd/connection.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c -index 3f19b9765..8ef115691 100644 ---- a/ldap/servers/slapd/connection.c -+++ b/ldap/servers/slapd/connection.c -@@ -2176,6 +2176,13 @@ log_ber_too_big_error(const Connection *conn, ber_len_t ber_len, ber_len_t maxbe - " is %" BERLEN_T " bytes. Change the nsslapd-maxbersize attribute in" - " cn=config to increase.\n", - conn->c_connid, conn->c_sd, maxbersize); -+ } else if (ber_len < maxbersize) { -+ /* This means the request was misformed, not too large. */ -+ slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error", -+ "conn=%" PRIu64 " fd=%d Incoming BER Element may be misformed. " -+ "This may indicate an attempt to use TLS on a plaintext port, " -+ "IE ldaps://localhost:389. Check your client LDAP_URI settings.\n", -+ conn->c_connid, conn->c_sd); - } else { - slapi_log_err(SLAPI_LOG_ERR, "log_ber_too_big_error", - "conn=%" PRIu64 " fd=%d Incoming BER Element was %" BERLEN_T " bytes, max allowable" --- -2.13.6 - diff --git a/SOURCES/0036-Ticket-48118-At-startup-changelog-can-be-erronously-.patch b/SOURCES/0036-Ticket-48118-At-startup-changelog-can-be-erronously-.patch deleted file mode 100644 index 1aa02b6..0000000 --- a/SOURCES/0036-Ticket-48118-At-startup-changelog-can-be-erronously-.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 127e0d954eb7741c4afdc0305f7970b7ea164e8d Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Thu, 9 Nov 2017 11:28:34 +0100 -Subject: [PATCH] Ticket 48118 - At startup, changelog can be erronously - rebuilt after a normal shutdown - - Problem: There are two problems that can lead to inconsistent database and changelog maxruv: - 1] the database ruv is written periodically in th ehouskeeping thread and at shutdown. It - relies on teh ruv_dirty flag, but due to a race condition this can be reset befor writing - the ruv - 2] the changelog max ruv is updated whenever an operation is commutted, but in case of internal - operations inside the txn for a client operation, if the operation is aborted the cl maxruv - is not reset. Since it is only written at shutdown this normally is no problem, but if the - aborted operation is the last before shutdown or is aborted by shutdown the cl ruv is incorrect - - Fix: the fix is in two parts: - 1] remove the use of the dirty flag, ensure that the ruv is always written. The overhead for writing - a database ruv that has not changed is minimal - 2] when writing the changelog maxruv check if the macsns it contains are really present in the - changelog. If not the maxruv is not written, it will be reconstructed at the next startup - - Reviewed by: William,Thierry - Thanks ---- - ldap/servers/plugins/replication/cl5_api.c | 39 ++++++++++++++++++++++ - ldap/servers/plugins/replication/repl5.h | 1 - - ldap/servers/plugins/replication/repl5_replica.c | 32 +----------------- - .../plugins/replication/repl5_replica_config.c | 2 -- - 4 files changed, 40 insertions(+), 34 deletions(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index ec648c014..55032dfb0 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -250,6 +250,8 @@ static void _cl5ReadBerval(struct berval *bv, char **buff); - static void _cl5WriteBerval(struct berval *bv, char **buff); - static int _cl5ReadBervals(struct berval ***bv, char **buff, unsigned int size); - static int _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size); -+static int64_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv); -+static int64_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg); - - /* replay iteration */ - #ifdef FOR_DEBUGGING -@@ -2716,6 +2718,36 @@ _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size) - return CL5_SUCCESS; - } - -+static int64_t -+_cl5CheckCSNinCL(const ruv_enum_data *element, void *arg) -+{ -+ CL5DBFile *file = (CL5DBFile *)arg; -+ int rc = 0; -+ -+ DBT key = {0}, data = {0}; -+ char csnStr[CSN_STRSIZE]; -+ -+ /* construct the key */ -+ key.data = csn_as_string(element->csn, PR_FALSE, csnStr); -+ key.size = CSN_STRSIZE; -+ -+ data.flags = DB_DBT_MALLOC; -+ -+ rc = file->db->get(file->db, NULL /*txn*/, &key, &data, 0); -+ -+ slapi_ch_free(&(data.data)); -+ return rc; -+} -+ -+static int64_t -+_cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv) -+{ -+ int rc = 0; -+ -+ rc = ruv_enumerate_elements(maxruv, _cl5CheckCSNinCL, (void *)file); -+ -+ return rc; -+} - /* upgrade from db33 to db41 - * 1. Run recovery on the database environment using the DB_ENV->open method - * 2. Remove any Berkeley DB environment using the DB_ENV->remove method -@@ -4010,6 +4042,13 @@ _cl5WriteRUV(CL5DBFile *file, PRBool purge) - rc = ruv_to_bervals(file->maxRUV, &vals); - } - -+ if (!purge && _cl5CheckMaxRUV(file, file->maxRUV)) { -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, -+ "_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n", -+ file->name); -+ return CL5_DB_ERROR; -+ } -+ - key.size = CSN_STRSIZE; - - rc = _cl5WriteBervals(vals, &buff, &data.size); -diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h -index c6e79b7e2..4e206a0fc 100644 ---- a/ldap/servers/plugins/replication/repl5.h -+++ b/ldap/servers/plugins/replication/repl5.h -@@ -725,7 +725,6 @@ Object *replica_get_for_backend(const char *be_name); - void replica_set_purge_delay(Replica *r, uint32_t purge_delay); - void replica_set_tombstone_reap_interval(Replica *r, long interval); - void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv); --void replica_set_ruv_dirty(Replica *r); - Slapi_Entry *get_in_memory_ruv(Slapi_DN *suffix_sdn); - int replica_write_ruv(Replica *r); - char *replica_get_dn(Replica *r); -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index e5296bf1c..77f4f18e4 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -41,7 +41,6 @@ struct replica - ReplicaType repl_type; /* is this replica read-only ? */ - ReplicaId repl_rid; /* replicaID */ - Object *repl_ruv; /* replica update vector */ -- PRBool repl_ruv_dirty; /* Dirty flag for ruv */ - CSNPL *min_csn_pl; /* Pending list for minimal CSN */ - void *csn_pl_reg_id; /* registration assignment for csn callbacks */ - unsigned long repl_state_flags; /* state flags */ -@@ -788,7 +787,6 @@ replica_set_ruv(Replica *r, RUV *ruv) - } - - r->repl_ruv = object_new((void *)ruv, (FNFree)ruv_destroy); -- r->repl_ruv_dirty = PR_TRUE; - - replica_unlock(r->repl_lock); - } -@@ -860,9 +858,6 @@ replica_update_ruv(Replica *r, const CSN *updated_csn, const char *replica_purl) - "to update RUV for replica %s, csn = %s\n", - slapi_sdn_get_dn(r->repl_root), - csn_as_string(updated_csn, PR_FALSE, csn_str)); -- } else { -- /* RUV updated - mark as dirty */ -- r->repl_ruv_dirty = PR_TRUE; - } - } else { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, -@@ -1347,8 +1342,6 @@ replica_dump(Replica *r) - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tupdate dn: %s\n", - updatedn_list ? updatedn_list : "not configured"); - slapi_ch_free_string(&updatedn_list); -- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\truv: %s configured and is %sdirty\n", -- r->repl_ruv ? "" : "not", r->repl_ruv_dirty ? "" : "not "); - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tCSN generator: %s configured\n", - r->repl_csngen ? "" : "not"); - /* JCMREPL - Dump Referrals */ -@@ -1675,7 +1668,6 @@ replica_check_for_data_reload(Replica *r, void *arg __attribute__((unused))) - - ruv_force_csn_update_from_ruv(upper_bound_ruv, r_ruv, - "Force update of database RUV (from CL RUV) -> ", SLAPI_LOG_NOTICE); -- replica_set_ruv_dirty(r); - } - - } else { -@@ -2778,11 +2770,6 @@ replica_write_ruv(Replica *r) - - replica_lock(r->repl_lock); - -- if (!r->repl_ruv_dirty) { -- replica_unlock(r->repl_lock); -- return rc; -- } -- - PR_ASSERT(r->repl_ruv); - - ruv_to_smod((RUV *)object_get_data(r->repl_ruv), &smod); -@@ -2817,14 +2804,10 @@ replica_write_ruv(Replica *r) - /* ruv does not exist - create one */ - replica_lock(r->repl_lock); - -- if (rc == LDAP_SUCCESS) { -- r->repl_ruv_dirty = PR_FALSE; -- } else if (rc == LDAP_NO_SUCH_OBJECT) { -+ if (rc == LDAP_NO_SUCH_OBJECT) { - /* this includes an internal operation - but since this only happens - during server startup - its ok that we have lock around it */ - rc = _replica_configure_ruv(r, PR_TRUE); -- if (rc == 0) -- r->repl_ruv_dirty = PR_FALSE; - } else /* error */ - { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, -@@ -3325,7 +3308,6 @@ replica_create_ruv_tombstone(Replica *r) - - if (ruv_init_new(csnstr, r->repl_rid, purl, &ruv) == RUV_SUCCESS) { - r->repl_ruv = object_new((void *)ruv, (FNFree)ruv_destroy); -- r->repl_ruv_dirty = PR_TRUE; - return_value = LDAP_SUCCESS; - } else { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_create_ruv_tombstone - " -@@ -3365,8 +3347,6 @@ replica_create_ruv_tombstone(Replica *r) - slapi_add_internal_pb(pb); - e = NULL; /* add consumes e, upon success or failure */ - slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value); -- if (return_value == LDAP_SUCCESS) -- r->repl_ruv_dirty = PR_FALSE; - - done: - slapi_entry_free(e); -@@ -3630,7 +3610,6 @@ replica_strip_cleaned_rids(Replica *r) - ruv_get_cleaned_rids(ruv, rid); - while (rid[i] != 0) { - ruv_delete_replica(ruv, rid[i]); -- replica_set_ruv_dirty(r); - if (replica_write_ruv(r)) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, - "replica_strip_cleaned_rids - Failed to write RUV\n"); -@@ -3744,15 +3723,6 @@ replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv) - } - } - --void --replica_set_ruv_dirty(Replica *r) --{ -- PR_ASSERT(r); -- replica_lock(r->repl_lock); -- r->repl_ruv_dirty = PR_TRUE; -- replica_unlock(r->repl_lock); --} -- - PRBool - replica_is_state_flag_set(Replica *r, int32_t flag) - { -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 9c8d6adbb..e025f34d8 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -937,7 +937,6 @@ replica_config_change_type_and_id(Replica *r, const char *new_type, const char * - replica_reset_csn_pl(r); - } - ruv_delete_replica(ruv, oldrid); -- replica_set_ruv_dirty(r); - cl5CleanRUV(oldrid); - replica_set_csn_assigned(r); - } -@@ -1323,7 +1322,6 @@ replica_execute_cleanruv_task(Object *r, ReplicaId rid, char *returntext __attri - return LDAP_UNWILLING_TO_PERFORM; - } - rc = ruv_delete_replica(local_ruv, rid); -- replica_set_ruv_dirty(replica); - if (replica_write_ruv(replica)) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task - Could not write RUV\n"); - } --- -2.13.6 - diff --git a/SOURCES/0036-Ticket-7662-db2index-not-properly-evalauating-argume.patch b/SOURCES/0036-Ticket-7662-db2index-not-properly-evalauating-argume.patch new file mode 100644 index 0000000..a088384 --- /dev/null +++ b/SOURCES/0036-Ticket-7662-db2index-not-properly-evalauating-argume.patch @@ -0,0 +1,72 @@ +From 0ac013079796cafb119379e40f24559187935851 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0037-Ticket-48118-fix-compiler-warning-for-incorrect-retu.patch b/SOURCES/0037-Ticket-48118-fix-compiler-warning-for-incorrect-retu.patch deleted file mode 100644 index f592cba..0000000 --- a/SOURCES/0037-Ticket-48118-fix-compiler-warning-for-incorrect-retu.patch +++ /dev/null @@ -1,45 +0,0 @@ -From fd06b282ffd06a5b3807c0396bff442f0c7568b1 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Wed, 15 Nov 2017 13:17:00 +0100 -Subject: [PATCH] Ticket 48118 - fix compiler warning for incorrect return type - ---- - ldap/servers/plugins/replication/cl5_api.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index 55032dfb0..721013abf 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -250,8 +250,8 @@ static void _cl5ReadBerval(struct berval *bv, char **buff); - static void _cl5WriteBerval(struct berval *bv, char **buff); - static int _cl5ReadBervals(struct berval ***bv, char **buff, unsigned int size); - static int _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size); --static int64_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv); --static int64_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg); -+static int32_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv); -+static int32_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg); - - /* replay iteration */ - #ifdef FOR_DEBUGGING -@@ -2718,7 +2718,7 @@ _cl5WriteBervals(struct berval **bv, char **buff, u_int32_t *size) - return CL5_SUCCESS; - } - --static int64_t -+static int32_t - _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg) - { - CL5DBFile *file = (CL5DBFile *)arg; -@@ -2739,7 +2739,7 @@ _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg) - return rc; - } - --static int64_t -+static int32_t - _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv) - { - int rc = 0; --- -2.13.6 - diff --git a/SOURCES/0037-Ticket-49075-Adjust-logging-severity-levels.patch b/SOURCES/0037-Ticket-49075-Adjust-logging-severity-levels.patch new file mode 100644 index 0000000..8f0890d --- /dev/null +++ b/SOURCES/0037-Ticket-49075-Adjust-logging-severity-levels.patch @@ -0,0 +1,71 @@ +From d3771cf05358c0230c8c77d7f7dabe9219ea7c8c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0038-Ticket-49231-Fix-backport-issue.patch b/SOURCES/0038-Ticket-49231-Fix-backport-issue.patch new file mode 100644 index 0000000..ba41c98 --- /dev/null +++ b/SOURCES/0038-Ticket-49231-Fix-backport-issue.patch @@ -0,0 +1,62 @@ +From e0d5f86c9410bd29c0e4636d3072b24228e60128 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0038-Ticket-49298-Correct-error-codes-with-config-restore.patch b/SOURCES/0038-Ticket-49298-Correct-error-codes-with-config-restore.patch deleted file mode 100644 index 5e0db58..0000000 --- a/SOURCES/0038-Ticket-49298-Correct-error-codes-with-config-restore.patch +++ /dev/null @@ -1,210 +0,0 @@ -From e3dea0043973faf42f7756d840bc55aa8f143eb1 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Wed, 15 Nov 2017 13:44:02 +1000 -Subject: [PATCH] Ticket 49298 - Correct error codes with config restore. - -Bug Description: The piece of code uses 0 as an error - not 1, -and in some cases did not even check the codes or use the -correct logic. - -Fix Description: Cleanup dse_check_file to better check the -content of files and communicate issues to the admin. Correct -slapd_bootstrap_config to correctly handle the cases of removal -and restore. - -https://pagure.io/389-ds-base/issue/49298 - -Author: wibrown - -Review by: mreynoolds & spichugi - -Signed-off-by: Mark Reynolds -(cherry picked from commit 75e55e26579955adf058e8adcba9a28779583b7b) ---- - .../suites/config/removed_config_49298_test.py | 81 ++++++++++++++++++++++ - ldap/servers/slapd/config.c | 15 ++-- - ldap/servers/slapd/dse.c | 42 ++++++++--- - 3 files changed, 119 insertions(+), 19 deletions(-) - create mode 100644 dirsrvtests/tests/suites/config/removed_config_49298_test.py - -diff --git a/dirsrvtests/tests/suites/config/removed_config_49298_test.py b/dirsrvtests/tests/suites/config/removed_config_49298_test.py -new file mode 100644 -index 000000000..e65236924 ---- /dev/null -+++ b/dirsrvtests/tests/suites/config/removed_config_49298_test.py -@@ -0,0 +1,81 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2017 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+import pytest -+import os -+import logging -+import subprocess -+ -+from lib389.topologies import topology_st as topo -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+def test_restore_config(topo): -+ """ -+ Check that if a dse.ldif and backup are removed, that the server still starts. -+ -+ :id: e1c38fa7-30bc-46f2-a934-f8336f387581 -+ :setup: Standalone instance -+ :steps: -+ 1. Stop the instance -+ 2. Delete 'dse.ldif' -+ 3. Start the instance -+ :expectedresults: -+ 1. Steps 1 and 2 succeed. -+ 2. Server will succeed to start with restored cfg. -+ """ -+ topo.standalone.stop() -+ -+ dse_path = topo.standalone.get_config_dir() -+ -+ log.info(dse_path) -+ -+ for i in ('dse.ldif', 'dse.ldif.startOK'): -+ p = os.path.join(dse_path, i) -+ os.remove(p) -+ -+ # This will pass. -+ topo.standalone.start() -+ -+def test_removed_config(topo): -+ """ -+ Check that if a dse.ldif and backup are removed, that the server -+ exits better than "segfault". -+ -+ :id: b45272d1-c197-473e-872f-07257fcb2ec0 -+ :setup: Standalone instance -+ :steps: -+ 1. Stop the instance -+ 2. Delete 'dse.ldif', 'dse.ldif.bak', 'dse.ldif.startOK' -+ 3. Start the instance -+ :expectedresults: -+ 1. Steps 1 and 2 succeed. -+ 2. Server will fail to start, but will not crash. -+ """ -+ topo.standalone.stop() -+ -+ dse_path = topo.standalone.get_config_dir() -+ -+ log.info(dse_path) -+ -+ for i in ('dse.ldif', 'dse.ldif.bak', 'dse.ldif.startOK'): -+ p = os.path.join(dse_path, i) -+ os.remove(p) -+ -+ # We actually can't check the log output, because it can't read dse.ldif, -+ # don't know where to write it yet! All we want is the server fail to -+ # start here, rather than infinite run + segfault. -+ with pytest.raises(subprocess.CalledProcessError): -+ topo.standalone.start() -+ -+ -diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c -index afe07df84..c8d57e747 100644 ---- a/ldap/servers/slapd/config.c -+++ b/ldap/servers/slapd/config.c -@@ -121,14 +121,13 @@ slapd_bootstrap_config(const char *configdir) - "Passed null config directory\n"); - return rc; /* Fail */ - } -- PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir, -- CONFIG_FILENAME); -- PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir, -- CONFIG_FILENAME); -- if ((rc = dse_check_file(configfile, tmpfile)) == 0) { -- PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.bak", configdir, -- CONFIG_FILENAME); -- rc = dse_check_file(configfile, tmpfile); -+ PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir, CONFIG_FILENAME); -+ PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.bak", configdir, CONFIG_FILENAME); -+ rc = dse_check_file(configfile, tmpfile); -+ if (rc == 0) { -+ /* EVERYTHING IS GOING WRONG, ARRGHHHHHH */ -+ slapi_log_err(SLAPI_LOG_ERR, "slapd_bootstrap_config", "No valid configurations can be accessed! You must restore %s from backup!\n", configfile); -+ return 0; - } - - if ((rc = PR_GetFileInfo64(configfile, &prfinfo)) != PR_SUCCESS) { -diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c -index 420248c24..653009f53 100644 ---- a/ldap/servers/slapd/dse.c -+++ b/ldap/servers/slapd/dse.c -@@ -609,29 +609,49 @@ dse_check_file(char *filename, char *backupname) - - if (PR_GetFileInfo64(filename, &prfinfo) == PR_SUCCESS) { - if (prfinfo.size > 0) { -- return (1); -+ /* File exists and has content. */ -+ return 1; - } else { -+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -+ "The config %s has zero length. Attempting restore ... \n", filename, rc); - rc = PR_Delete(filename); - } -+ } else { -+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -+ "The config %s can not be accessed. Attempting restore ... (reason: %d)\n", filename, rc); - } - - if (backupname) { -+ -+ if (PR_GetFileInfo64(backupname, &prfinfo) != PR_SUCCESS) { -+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -+ "The backup %s can not be accessed. Check it exists and permissions.\n", backupname); -+ return 0; -+ } -+ -+ if (prfinfo.size <= 0) { -+ slapi_log_err(SLAPI_LOG_ERR, "dse_check_file", -+ "The backup file %s has zero length, refusing to restore it.\n", backupname); -+ return 0; -+ } -+ - rc = PR_Rename(backupname, filename); -- } else { -- return (0); -- } -+ if (rc != PR_SUCCESS) { -+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -+ "The configuration file %s was NOT able to be restored from %s, error %d\n", filename, backupname, rc); -+ return 0; -+ } - -- if (PR_GetFileInfo64(filename, &prfinfo) == PR_SUCCESS && prfinfo.size > 0) { - slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -- "The configuration file %s was restored from backup %s\n", filename, backupname); -- return (1); -+ "The configuration file %s was restored from backup %s\n", filename, backupname); -+ return 1; -+ - } else { -- slapi_log_err(SLAPI_LOG_ERR, "dse_check_file", -- "The configuration file %s was not restored from backup %s, error %d\n", -- filename, backupname, rc); -- return (0); -+ slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", "No backup filename provided.\n"); -+ return 0; - } - } -+ - static int - dse_read_one_file(struct dse *pdse, const char *filename, Slapi_PBlock *pb, int primary_file) - { --- -2.13.6 - diff --git a/SOURCES/0039-Ticket-49231-Fix-backport-issue-part2.patch b/SOURCES/0039-Ticket-49231-Fix-backport-issue-part2.patch new file mode 100644 index 0000000..e9411e1 --- /dev/null +++ b/SOURCES/0039-Ticket-49231-Fix-backport-issue-part2.patch @@ -0,0 +1,25 @@ +From fe06dee8f346a8d8ded338bb5080c4cd3b230eef Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0039-Ticket-49474-sasl-allow-mechs-does-not-operate-corre.patch b/SOURCES/0039-Ticket-49474-sasl-allow-mechs-does-not-operate-corre.patch deleted file mode 100644 index 7ba646d..0000000 --- a/SOURCES/0039-Ticket-49474-sasl-allow-mechs-does-not-operate-corre.patch +++ /dev/null @@ -1,99 +0,0 @@ -From bfaf5b56bb1a416c5e058a9925642098c87e0330 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Thu, 30 Nov 2017 14:06:59 +0100 -Subject: [PATCH] Ticket 49474 - sasl allow mechs does not operate correctly - -Bug Description: In a fix to sasl allowed mechs, the logic -was not properly configured. - -Fix Description: Alter the ids_sasl_supported_mech to be -clearer and simpler in it's design. - -https://pagure.io/389-ds-base/issue/49474 - -Author: wibrown - -Review by: tbordaz (Thank you!) - -Cherry picked from f75cfbce07b79272a7f1a2e387dc232d45c169f5 ---- - ldap/servers/slapd/saslbind.c | 49 ++++++++----------------------------------- - 1 file changed, 9 insertions(+), 40 deletions(-) - -diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c -index 6734c32a7..67da97148 100644 ---- a/ldap/servers/slapd/saslbind.c -+++ b/ldap/servers/slapd/saslbind.c -@@ -835,52 +835,21 @@ ids_sasl_listmech(Slapi_PBlock *pb) - static int - ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech) - { -- int i, ret = 0; -- char **mechs; -- char **allowed_mechs = NULL; -- char *dupstr; -- const char *str; -- int sasl_result = 0; -- Connection *pb_conn = NULL; -- -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- sasl_conn_t *sasl_conn = (sasl_conn_t *)pb_conn->c_sasl_conn; - slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "=>\n"); - -- /* sasl_listmech is not thread-safe - caller must lock pb_conn */ -- sasl_result = sasl_listmech(sasl_conn, -- NULL, /* username */ -- "", ",", "", -- &str, NULL, NULL); -- if (sasl_result != SASL_OK) { -- return 0; -- } -- -- dupstr = slapi_ch_strdup(str); -- mechs = slapi_str2charray(dupstr, ","); -- allowed_mechs = config_get_allowed_sasl_mechs_array(); -+ char **allowed_mechs = ids_sasl_listmech(pb); - -- for (i = 0; mechs[i] != NULL; i++) { -- if (strcasecmp(mech, mechs[i]) == 0) { -- if (allowed_mechs) { -- if (charray_inlist(allowed_mechs, (char *)mech) == 0) { -- ret = 1; -- } -- break; -- } else { -- ret = 1; -- break; -- } -- } -+ /* 0 indicates "now allowed" */ -+ int allowed_mech_present = 0; -+ if (allowed_mechs != NULL) { -+ /* Returns 1 if present and allowed. */ -+ allowed_mech_present = charray_inlist(allowed_mechs, (char *)mech); -+ charray_free(allowed_mechs); - } - -- charray_free(allowed_mechs); -- charray_free(mechs); -- slapi_ch_free((void **)&dupstr); -- - slapi_log_err(SLAPI_LOG_TRACE, "ids_sasl_mech_supported", "<=\n"); - -- return ret; -+ return allowed_mech_present; - } - - /* -@@ -944,7 +913,7 @@ ids_sasl_check_bind(Slapi_PBlock *pb) - * different error code to SASL_NOMECH. Must be called - * while holding the pb_conn lock - */ -- if (!ids_sasl_mech_supported(pb, mech)) { -+ if (ids_sasl_mech_supported(pb, mech) == 0) { - rc = SASL_NOMECH; - goto sasl_check_result; - } --- -2.13.6 - diff --git a/SOURCES/0040-Ticket-48681-logconv.pl-Fix-SASL-Bind-stats-and-rewo.patch b/SOURCES/0040-Ticket-48681-logconv.pl-Fix-SASL-Bind-stats-and-rewo.patch new file mode 100644 index 0000000..7fae21f --- /dev/null +++ b/SOURCES/0040-Ticket-48681-logconv.pl-Fix-SASL-Bind-stats-and-rewo.patch @@ -0,0 +1,130 @@ +From e78c098543bbf64b03d1f3df98aa26184c435737 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0040-Ticket-49470-overflow-in-pblock_get.patch b/SOURCES/0040-Ticket-49470-overflow-in-pblock_get.patch deleted file mode 100644 index 6c9225b..0000000 --- a/SOURCES/0040-Ticket-49470-overflow-in-pblock_get.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 30fa0e4c993d4a91a90327329b50f02e637fe049 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Tue, 28 Nov 2017 15:31:25 +0100 -Subject: [PATCH] Ticket 49470 - overflow in pblock_get - -Bug Description: While getting the connection id we used an int -not a uint64_t - -Fix Description: Make the stack size uint64_t instead. - -https://pagure.io/389-ds-base/issue/49470 - -Author: wibrown - -Review by: tbordaz ---- - ldap/servers/slapd/modify.c | 5 +++-- - ldap/servers/slapd/pblock.c | 4 ++-- - ldap/servers/slapd/slap.h | 2 +- - 3 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c -index 6309975ae..0dcac646b 100644 ---- a/ldap/servers/slapd/modify.c -+++ b/ldap/servers/slapd/modify.c -@@ -281,11 +281,12 @@ do_modify(Slapi_PBlock *pb) - - if (ignored_some_mods && (0 == smods.num_elements)) { - if (pb_conn->c_isreplication_session) { -- int connid, opid; -+ uint64_t connid; -+ int32_t opid; - slapi_pblock_get(pb, SLAPI_CONN_ID, &connid); - slapi_pblock_get(pb, SLAPI_OPERATION_ID, &opid); - slapi_log_err(SLAPI_LOG_ERR, "do_modify", -- "Rejecting replicated password policy operation(conn=%d op=%d) for " -+ "Rejecting replicated password policy operation(conn=%"PRIu64" op=%d) for " - "entry %s. To allow these changes to be accepted, set passwordIsGlobalPolicy to 'on' in " - "cn=config.\n", - connid, opid, rawdn); -diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c -index 8f87de5b5..4514c3ce6 100644 ---- a/ldap/servers/slapd/pblock.c -+++ b/ldap/servers/slapd/pblock.c -@@ -412,7 +412,7 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value) - "slapi_pblock_get", "Connection is NULL and hence cannot access SLAPI_CONN_ID \n"); - return (-1); - } -- (*(PRUint64 *)value) = pblock->pb_conn->c_connid; -+ (*(uint64_t *)value) = pblock->pb_conn->c_connid; - break; - case SLAPI_CONN_DN: - /* -@@ -2538,7 +2538,7 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value) - "slapi_pblock_set", "Connection is NULL and hence cannot access SLAPI_CONN_ID \n"); - return (-1); - } -- pblock->pb_conn->c_connid = *((PRUint64 *)value); -+ pblock->pb_conn->c_connid = *((uint64_t *)value); - break; - case SLAPI_CONN_DN: - /* -diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h -index 44632580a..830944f72 100644 ---- a/ldap/servers/slapd/slap.h -+++ b/ldap/servers/slapd/slap.h -@@ -1604,7 +1604,7 @@ typedef struct conn - int c_gettingber; /* in the middle of ber_get_next */ - BerElement *c_currentber; /* ber we're getting */ - time_t c_starttime; /* when the connection was opened */ -- PRUint64 c_connid; /* id of this connection for stats*/ -+ uint64_t c_connid; /* id of this connection for stats*/ - PRUint64 c_maxthreadscount; /* # of times a conn hit max threads */ - PRUint64 c_maxthreadsblocked; /* # of operations blocked by maxthreads */ - int c_opsinitiated; /* # ops initiated/next op id */ --- -2.13.6 - diff --git a/SOURCES/0041-Ticket-49157-ds-logpipe.py-crashes-for-non-existing-.patch b/SOURCES/0041-Ticket-49157-ds-logpipe.py-crashes-for-non-existing-.patch new file mode 100644 index 0000000..b8004e0 --- /dev/null +++ b/SOURCES/0041-Ticket-49157-ds-logpipe.py-crashes-for-non-existing-.patch @@ -0,0 +1,83 @@ +From a842e43becb9312574071b1460bfa835bfecc47b Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0041-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch b/SOURCES/0041-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch deleted file mode 100644 index 14a79cd..0000000 --- a/SOURCES/0041-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 25844922007eea26f78d18171e51be3aa7b5e949 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Wed, 6 Dec 2017 15:14:57 +0100 -Subject: [PATCH] Ticket 49471 - heap-buffer-overflow in ss_unescape - -Bug Description: - Two problems here - - when searching for wildcard and escape char, ss_unescape assumes the string - is at least 3 chars longs. So memcmp can overflow a shorter string - - while splitting a string into substring pattern, it loops over - wildcard and can overpass the string end - -Fix Description: - For the first problem, it checks the string size is long enough to memcmp - a wildcard or an escape - For the second it exits from the loop as soon as the end of the string is reached - -https://pagure.io/389-ds-base/issue/49471 - -Reviewed by: William Brown - -Platforms tested: F23 - -Flag Day: no - -Doc impact: no - -(cherry picked from commit 5991388ce75fba8885579b769711d57acfd43cd3) ---- - dirsrvtests/tests/tickets/ticket49471_test.py | 79 +++++++++++++++++++++++++++ - ldap/servers/plugins/collation/orfilter.c | 14 +++-- - 2 files changed, 87 insertions(+), 6 deletions(-) - create mode 100644 dirsrvtests/tests/tickets/ticket49471_test.py - -diff --git a/dirsrvtests/tests/tickets/ticket49471_test.py b/dirsrvtests/tests/tickets/ticket49471_test.py -new file mode 100644 -index 000000000..0456a5182 ---- /dev/null -+++ b/dirsrvtests/tests/tickets/ticket49471_test.py -@@ -0,0 +1,79 @@ -+import logging -+import pytest -+import os -+import time -+import ldap -+from lib389._constants import * -+from lib389.topologies import topology_st as topo -+from lib389 import Entry -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+ -+USER_CN='user_' -+def _user_get_dn(no): -+ cn = '%s%d' % (USER_CN, no) -+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX) -+ return (cn, dn) -+ -+def add_user(server, no, desc='dummy', sleep=True): -+ (cn, dn) = _user_get_dn(no) -+ log.fatal('Adding user (%s): ' % dn) -+ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser', 'userSecurityInformation'], -+ 'cn': [cn], -+ 'description': [desc], -+ 'sn': [cn], -+ 'description': ['add on that host']}))) -+ if sleep: -+ time.sleep(2) -+ -+def test_ticket49471(topo): -+ """Specify a test case purpose or name here -+ -+ :id: 457ab172-9455-4eb2-89a0-150e3de5993f -+ :setup: Fill in set up configuration here -+ :steps: -+ 1. Fill in test case steps here -+ 2. And indent them like this (RST format requirement) -+ :expectedresults: -+ 1. Fill in the result that is expected -+ 2. For each test step -+ """ -+ -+ # If you need any test suite initialization, -+ # please, write additional fixture for that (including finalizer). -+ # Topology for suites are predefined in lib389/topologies.py. -+ -+ # If you need host, port or any other data about instance, -+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid) -+ -+ S1 = topo.standalone -+ add_user(S1, 1) -+ -+ Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*on\*)" -+ ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter) -+ assert len(ents) == 1 -+ -+ # -+ # The following is for the test 49491 -+ # skipped here else it crashes in ASAN -+ #Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*host)" -+ #ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter) -+ #assert len(ents) == 1 -+ -+ if DEBUGGING: -+ # Add debugging steps(if any)... -+ pass -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c -index 5a2d8a0ab..a98d90219 100644 ---- a/ldap/servers/plugins/collation/orfilter.c -+++ b/ldap/servers/plugins/collation/orfilter.c -@@ -313,12 +313,12 @@ ss_unescape(struct berval *val) - char *t = s; - char *limit = s + val->bv_len; - while (s < limit) { -- if (!memcmp(s, "\\2a", 3) || -- !memcmp(s, "\\2A", 3)) { -+ if (((limit - s) >= 3) && -+ (!memcmp(s, "\\2a", 3) || !memcmp(s, "\\2A", 3))) { - *t++ = WILDCARD; - s += 3; -- } else if (!memcmp(s, "\\5c", 3) || -- !memcmp(s, "\\5C", 3)) { -+ } else if ((limit - s) >= 3 && -+ (!memcmp(s, "\\5c", 3) || !memcmp(s, "\\5C", 3))) { - *t++ = '\\'; - s += 3; - } else { -@@ -409,13 +409,15 @@ ss_filter_values(struct berval *pattern, int *query_op) - switch (*p) { - case WILDCARD: - result[n++] = ss_filter_value(s, p - s, &val); -- while (++p != plimit && *p == WILDCARD) -- ; -+ while (p != plimit && *p == WILDCARD) p++; - s = p; - break; - default: - break; - } -+ if (p >= plimit) { -+ break; -+ } - } - if (p != s || s == plimit) { - result[n++] = ss_filter_value(s, p - s, &val); --- -2.13.6 - diff --git a/SOURCES/0042-Ticket-49249-cos_cache-is-erroneously-logging-schema.patch b/SOURCES/0042-Ticket-49249-cos_cache-is-erroneously-logging-schema.patch new file mode 100644 index 0000000..66faff3 --- /dev/null +++ b/SOURCES/0042-Ticket-49249-cos_cache-is-erroneously-logging-schema.patch @@ -0,0 +1,202 @@ +From 834b5f7355d4233c4b9d6931ba6ec8482413bca8 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0042-Ticket-49298-fix-complier-warn.patch b/SOURCES/0042-Ticket-49298-fix-complier-warn.patch deleted file mode 100644 index 8cc97dc..0000000 --- a/SOURCES/0042-Ticket-49298-fix-complier-warn.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 189c3ce4d5b5c9341a60d4056dad26133d9607ca Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Fri, 17 Nov 2017 11:43:36 +1000 -Subject: [PATCH] Ticket 49298 - fix complier warn - -Bug Description: Extra argument to error log in dse.c - -Fix Description: Remove extra argument. - -https://pagure.io/389-ds-base/issue/49298 - -Author: wibrown - -Review by: oneline rule. ---- - ldap/servers/slapd/dse.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c -index 653009f53..662e91aa7 100644 ---- a/ldap/servers/slapd/dse.c -+++ b/ldap/servers/slapd/dse.c -@@ -613,7 +613,7 @@ dse_check_file(char *filename, char *backupname) - return 1; - } else { - slapi_log_err(SLAPI_LOG_INFO, "dse_check_file", -- "The config %s has zero length. Attempting restore ... \n", filename, rc); -+ "The config %s has zero length. Attempting restore ... \n", filename); - rc = PR_Delete(filename); - } - } else { --- -2.13.6 - diff --git a/SOURCES/0043-Ticket-49238-AddressSanitizer-heap-use-after-free-in.patch b/SOURCES/0043-Ticket-49238-AddressSanitizer-heap-use-after-free-in.patch new file mode 100644 index 0000000..5e1b21b --- /dev/null +++ b/SOURCES/0043-Ticket-49238-AddressSanitizer-heap-use-after-free-in.patch @@ -0,0 +1,243 @@ +From 4182dd8bbff22f9e0e45b763a4619c0bc8dcb153 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0043-Ticket-49495-Fix-memory-management-is-vattr.patch b/SOURCES/0043-Ticket-49495-Fix-memory-management-is-vattr.patch deleted file mode 100644 index 670891a..0000000 --- a/SOURCES/0043-Ticket-49495-Fix-memory-management-is-vattr.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 2c56e7dc08a41fc1dfa6a79213e93686f553847c Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Mon, 11 Dec 2017 15:48:24 +0100 -Subject: [PATCH] Ticket 49495 - Fix memory management is vattr. - -Bug Description: During the fix for -https://pagure.io/389-ds-base/issue/49436 a issue was exposed -in how registration of attributes to cos work. With the change -to handle -> attr link, this exposed that cos treats each attribute -and template pair as a new type for the handle. As aresult, this -caused the sp_list to create a long linked list of M*N entries -for each attr - template value. Obviously, this is extremely -slow to traverse during a search! - -Fix Description: Undo part of the SLL next change and convert -to reference counting. The issue remains that there is a defect -in how cos handles attribute registration, but this can not be -resolved without a significant rearchitecture of the code -related to virtual attributes. - -https://pagure.io/389-ds-base/issue/49495 - -Author: wibrown - -Review by: tbordaz, lkrispen (Thanks!) ---- - ldap/servers/plugins/cos/cos_cache.c | 28 +++++++++++----------------- - ldap/servers/slapd/vattr.c | 23 +++++++++++++++++++++-- - 2 files changed, 32 insertions(+), 19 deletions(-) - -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index 662dace35..3b3c05783 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -275,7 +275,7 @@ static Slapi_Mutex *start_lock; - static Slapi_Mutex *stop_lock; - static Slapi_CondVar *something_changed = NULL; - static Slapi_CondVar *start_cond = NULL; -- -+static vattr_sp_handle *vattr_handle = NULL; - - /* - cos_cache_init -@@ -314,6 +314,15 @@ cos_cache_init(void) - goto out; - } - -+ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, -+ cos_cache_vattr_get, -+ cos_cache_vattr_compare, -+ cos_cache_vattr_types) != 0) { -+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider\n"); -+ ret = -1; -+ goto out; -+ } -+ - /* grab the views interface */ - if (slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) { - /* lets be tolerant if views is disabled */ -@@ -847,22 +856,7 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data) - dnVals[valIndex]->bv_val); - } - -- /* -- * Each SP_handle is associated to one and only one vattr. -- * We could consider making this a single function rather -- * than the double-call. -- */ -- -- vattr_sp_handle *vattr_handle = NULL; -- -- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, -- cos_cache_vattr_get, -- cos_cache_vattr_compare, -- cos_cache_vattr_types) != 0) { -- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val); -- } else { -- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); -- } -+ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); - - } /* if(attrType is cosAttribute) */ - -diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c -index 432946c79..13e527188 100644 ---- a/ldap/servers/slapd/vattr.c -+++ b/ldap/servers/slapd/vattr.c -@@ -1544,6 +1544,7 @@ struct _vattr_sp_handle - vattr_sp *sp; - struct _vattr_sp_handle *next; /* So we can link them together in the map */ - void *hint; /* Hint to the SP */ -+ uint64_t rc; - }; - - /* Calls made by Service Providers */ -@@ -1770,7 +1771,7 @@ is a separate thing in the insterests of stability. - - */ - --#define VARRT_MAP_HASHTABLE_SIZE 10 -+#define VARRT_MAP_HASHTABLE_SIZE 32 - - /* Attribute map oject */ - /* Needs to contain: a linked list of pointers to provider handles handles, -@@ -1867,7 +1868,10 @@ vattr_map_entry_free(vattr_map_entry *vae) - vattr_sp_handle *list_entry = vae->sp_list; - while (list_entry != NULL) { - vattr_sp_handle *next_entry = list_entry->next; -- slapi_ch_free((void **)&list_entry); -+ if (slapi_atomic_decr_64(&(list_entry->rc), __ATOMIC_RELAXED) == 0) { -+ /* Only free on RC 0 */ -+ slapi_ch_free((void **)&list_entry); -+ } - list_entry = next_entry; - } - slapi_ch_free_string(&(vae->type_name)); -@@ -2280,6 +2284,17 @@ to handle the calls on it, but return nothing */ - * - * Better idea, is that regattr should just take the fn pointers - * and callers never *see* the sp_handle structure at all. -+ * -+ * This leaves us with some quirks today. First: if you have plugin A -+ * and B, A registers attr 1 and B 1 and 2, it's possible that if you -+ * register A1 first, then B1, you have B->A in next. Then when you -+ * register B2, because we take 0==result from map_lookup, we add sp -+ * "as is" to the map. This means that B2 now has the same next to A1 -+ * handle. This won't add a bug, because A1 won't be able to service the -+ * attr, but it could cause some head scratching ... -+ * -+ * Again, to fix this, the whole vattr external interface needs a -+ * redesign ... :( - */ - - int -@@ -2304,11 +2319,15 @@ vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint) - if (found) { - return 0; - } -+ /* Increase the ref count of the sphandle */ -+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED); - /* We insert the SP handle into the linked list at the head */ - sp->next = map_entry->sp_list; - map_entry->sp_list = sp; - } else { - /* If not, add it */ -+ /* Claim a reference on the sp ... */ -+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED); - map_entry = vattr_map_entry_new(type_to_add, sp, hint); - if (NULL == map_entry) { - return ENOMEM; --- -2.13.6 - diff --git a/SOURCES/0044-Ticket-49246-ns-slapd-crashes-in-role-cache-creation.patch b/SOURCES/0044-Ticket-49246-ns-slapd-crashes-in-role-cache-creation.patch new file mode 100644 index 0000000..5aafc3d --- /dev/null +++ b/SOURCES/0044-Ticket-49246-ns-slapd-crashes-in-role-cache-creation.patch @@ -0,0 +1,171 @@ +From 18491418e661b5dc1b9ca4c6bb4adb85bfb0bf0d Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0045-Ticket-49258-Allow-nsslapd-cache-autosize-to-be-modi.patch b/SOURCES/0045-Ticket-49258-Allow-nsslapd-cache-autosize-to-be-modi.patch new file mode 100644 index 0000000..07892e9 --- /dev/null +++ b/SOURCES/0045-Ticket-49258-Allow-nsslapd-cache-autosize-to-be-modi.patch @@ -0,0 +1,84 @@ +From e0cb3e9ff5337cfc4ecaa6fa5efa189b7bc16246 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0045-Ticket-49509-Indexing-of-internationalized-matching-.patch b/SOURCES/0045-Ticket-49509-Indexing-of-internationalized-matching-.patch deleted file mode 100644 index ec43a14..0000000 --- a/SOURCES/0045-Ticket-49509-Indexing-of-internationalized-matching-.patch +++ /dev/null @@ -1,239 +0,0 @@ -From 8d79d7c81157e77f4da595a723a6ed10a8e9789b Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Thu, 11 Jan 2018 18:52:43 +0100 -Subject: [PATCH] Ticket 49509 - Indexing of internationalized matching rules - is failing - -Bug Description: - Indexing of the internationalized matching rules tests if a - matching rule indexer handle or not a given OID. - A side effect of https://pagure.io/389-ds-base/issue/49097 is that - the returned indexing callbacks are lost. - Indeed, the indexing callbacks (and potentially others fields) were - stored in the temporary pblock that was memcpy to the provided - pblock in case of success - -Fix Description: - The fix basically restores the previous behavior but do not - memcpy pblock. It read/store the pblock fields that are - inputs/outputs of slapi_mr_indexer_create. - -https://pagure.io/389-ds-base/issue/49509 - -Reviewed by: Ludwig Krispenz - -Platforms tested: F23 - -Flag Day: no - -Doc impact: no ---- - ldap/servers/slapd/plugin_mr.c | 148 ++++++++++++++++++++++++++++------------- - 1 file changed, 103 insertions(+), 45 deletions(-) - -diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c -index bd2baff6c..ca4fe00e1 100644 ---- a/ldap/servers/slapd/plugin_mr.c -+++ b/ldap/servers/slapd/plugin_mr.c -@@ -143,6 +143,82 @@ plugin_mr_bind(char *oid, struct slapdplugin *plugin) - slapi_log_err(SLAPI_LOG_FILTER, "plugin_mr_bind", "<=\n"); - } - -+void -+mr_indexer_init_pb(Slapi_PBlock* src_pb, Slapi_PBlock* dst_pb) -+{ -+ char* oid; -+ char *type; -+ uint32_t usage; -+ void *object; -+ IFP destroyFn; -+ IFP indexFn, indexSvFn; -+ -+ /* matching rule plugin arguments */ -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_OID, &oid); -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_TYPE, &type); -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_USAGE, &usage); -+ -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_OID, oid); -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_TYPE, type); -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_USAGE, &usage); -+ -+ /* matching rule plugin functions */ -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); -+ -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn); -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn); -+ -+ /* common */ -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_OBJECT, &object); -+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_DESTROY_FN, &destroyFn); -+ -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_OBJECT, object); -+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_DESTROY_FN, destroyFn); -+ -+ -+} -+ -+/* -+ * Retrieves the matching rule plugin able to index/sort the provided OID/type -+ * -+ * The Matching rules able to index/sort a given OID are stored in a global list: global_mr_oids -+ * -+ * The retrieval is done in 3 phases: -+ * - It first searches (in global_mr_oids) for the already bound OID->MR -+ * - Else, look first in old style MR plugin -+ * for each registered 'syntax' and 'matchingrule' plugins having a -+ * SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, it binds (plugin_mr_bind) the first -+ * plugin that support the OID -+ * - Else, look in new style MR plugin -+ * for each registered 'syntax' and 'matchingrule' plugins, it binds (plugin_mr_bind) the first -+ * plugin that contains OID in its plg_mr_names -+ * -+ * Inputs: -+ * SLAPI_PLUGIN_MR_OID -+ * should contain the OID of the matching rule that you want used for indexing or sorting. -+ * SLAPI_PLUGIN_MR_TYPE -+ * should contain the attribute type that you want used for indexing or sorting. -+ * SLAPI_PLUGIN_MR_USAGE -+ * should specify if the indexer will be used for indexing (SLAPI_PLUGIN_MR_USAGE_INDEX) -+ * or for sorting (SLAPI_PLUGIN_MR_USAGE_SORT) -+ * -+ * -+ * Output: -+ * -+ * SLAPI_PLUGIN_MR_OID -+ * contain the OFFICIAL OID of the matching rule that you want used for indexing or sorting. -+ * SLAPI_PLUGIN_MR_INDEX_FN -+ * specifies the indexer function responsible for indexing or sorting of struct berval ** -+ * SLAPI_PLUGIN_MR_INDEX_SV_FN -+ * specifies the indexer function responsible for indexing or sorting of Slapi_Value ** -+ * SLAPI_PLUGIN_OBJECT -+ * contain any information that you want passed to the indexer function. -+ * SLAPI_PLUGIN_DESTROY_FN -+ * specifies the function responsible for freeing any memory allocated by this indexer factory function. -+ * For example, memory allocated for a structure that you pass to the indexer function using SLAPI_PLUGIN_OBJECT. -+ * -+ */ - int /* an LDAP error code, hopefully LDAP_SUCCESS */ - slapi_mr_indexer_create(Slapi_PBlock *opb) - { -@@ -152,28 +228,33 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */ - IFP createFn = NULL; - struct slapdplugin *mrp = plugin_mr_find_registered(oid); - if (mrp != NULL) { -+ /* Great the matching OID -> MR plugin was already found, just reuse it */ - if (!(rc = slapi_pblock_set(opb, SLAPI_PLUGIN, mrp)) && - !(rc = slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) && - createFn != NULL) { - rc = createFn(opb); - } - } else { -- /* call each plugin, until one is able to handle this request. */ -+ /* We need to find in the MR plugins list, the MR plugin that will be able to handle OID -+ * -+ * It can be "old style" MR plugin (i.e. collation) that define indexer -+ * -+ * It can be "now style" MR plugin that contain OID string in 'plg_mr_names' -+ * (ie. ces, cis, bin...) where plg_mr_names is defined in 'mr_plugin_table' in each file -+ * ces.c, cis.c... -+ * New style MR plugin have NULL indexer create function but rather use a default indexer -+ */ -+ -+ /* Look for a old syntax-style mr plugin -+ * call each plugin, until one is able to handle this request. -+ */ - rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; -- // We need to get the type and usage from the caller. -- char *type; -- uint32_t usage; -- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_TYPE, &type); -- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_USAGE, &usage); -+ - for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) { - - Slapi_PBlock *pb = slapi_pblock_new(); -+ mr_indexer_init_pb(opb, pb); - slapi_pblock_set(pb, SLAPI_PLUGIN, mrp); -- /* From filtercmp.c and matchrule.c, these are the values we need to set. into pb */ -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage); -- - /* This is associated with the pb_plugin struct, so it comes with mrp */ - if (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) { - /* plugin not a matchingrule type */ -@@ -185,14 +266,11 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */ - IFP indexFn = NULL; - IFP indexSvFn = NULL; - /* These however, are in the pblock direct, so we need to copy them. */ -- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); -- slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn); -+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); -+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); - if (indexFn || indexSvFn) { - /* Success: this plugin can handle it. */ -- /* call create on the opb? */ -- createFn(opb); -+ mr_indexer_init_pb(pb, opb); - plugin_mr_bind(oid, mrp); /* for future reference */ - rc = 0; /* success */ - slapi_pblock_destroy(pb); -@@ -205,37 +283,12 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */ - /* look for a new syntax-style mr plugin */ - struct slapdplugin *pi = plugin_mr_find(oid); - if (pi) { -- Slapi_PBlock *pb = slapi_pblock_new(); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type); -- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage); -- slapi_pblock_set(pb, SLAPI_PLUGIN, pi); -- rc = default_mr_indexer_create(pb); -+ slapi_pblock_set(opb, SLAPI_PLUGIN, pi); -+ rc = default_mr_indexer_create(opb); - if (!rc) { -- /* On success, copy the needed values in. These are added by default_mr_indexer_create */ -- void *pb_object = NULL; -- IFP destroy_fn = NULL; -- IFP index_fn = NULL; -- IFP index_sv_fn = NULL; -- -- slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &pb_object); -- slapi_pblock_get(pb, SLAPI_PLUGIN_DESTROY_FN, &destroy_fn); -- slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &index_fn); -- slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &index_sv_fn); -- -- /* SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, and SLAPI_PLUGIN_MR_FILTER_CREATE_FN, are part of pb_plugin */ -- slapi_pblock_set(opb, SLAPI_PLUGIN, pi); -- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_OID, oid); -- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_TYPE, type); -- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_USAGE, &usage); -- slapi_pblock_set(opb, SLAPI_PLUGIN_OBJECT, pb_object); -- slapi_pblock_set(opb, SLAPI_PLUGIN_DESTROY_FN, destroy_fn); -- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_FN, index_fn); -- slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, index_sv_fn); -- - plugin_mr_bind(oid, pi); /* for future reference */ - } -- slapi_pblock_destroy(pb); -+ slapi_pblock_set(opb, SLAPI_PLUGIN, NULL); - } - } - } -@@ -706,6 +759,11 @@ default_mr_indexer_create(Slapi_PBlock *pb) - slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn); - slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn); - slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy); -+ -+ /* Note the two following setting are in the slapdplugin struct SLAPI_PLUGIN -+ * so they are not really output of the function but will just -+ * be stored in the bound (OID <--> plugin) list (plugin_mr_find_registered/plugin_mr_bind) -+ */ - slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create); - slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create); - rc = 0; --- -2.13.6 - diff --git a/SOURCES/0046-Ticket-49261-Fix-script-usage-and-man-pages.patch b/SOURCES/0046-Ticket-49261-Fix-script-usage-and-man-pages.patch new file mode 100644 index 0000000..71857d0 --- /dev/null +++ b/SOURCES/0046-Ticket-49261-Fix-script-usage-and-man-pages.patch @@ -0,0 +1,156 @@ +From c0a50f26aa52bda451c5b5bce7fa2c7c2eb90fe6 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0046-Ticket-49493-heap-use-after-free-in-csn_as_string.patch b/SOURCES/0046-Ticket-49493-heap-use-after-free-in-csn_as_string.patch deleted file mode 100644 index 84d1d21..0000000 --- a/SOURCES/0046-Ticket-49493-heap-use-after-free-in-csn_as_string.patch +++ /dev/null @@ -1,155 +0,0 @@ -From a7a0db402b32dcec7fc93bcbef42174163ae9c12 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Tue, 12 Dec 2017 12:46:37 +0100 -Subject: [PATCH] Ticket 49493 - heap use after free in csn_as_string - -Bug: If write_changlog_and_ruv failed teh csn pending list was not properly - cleand and references to the prim csn were kept, but the prim csn was reset - -Fix: check the return code for the mmr postop plugin and aset error codes properly - that will triger cancel_opcsn - -Reviewed by: Thierry, thanks -Tested by: Viktor, thanks ---- - ldap/servers/slapd/back-ldbm/ldbm_add.c | 22 +--------------------- - ldap/servers/slapd/back-ldbm/ldbm_delete.c | 4 ++++ - ldap/servers/slapd/back-ldbm/ldbm_modify.c | 4 ++++ - ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 4 ++++ - ldap/servers/slapd/back-ldbm/misc.c | 18 ++++++++++++++++++ - ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1 + - 6 files changed, 32 insertions(+), 21 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c -index b7e17ad50..f29945a7e 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c -@@ -22,7 +22,6 @@ extern char *hassubordinates; - - static void delete_update_entrydn_operational_attributes(struct backentry *ep); - --static int set_error(Slapi_PBlock *pb, int retval, int ldap_result_code, char **ldap_result_message); - #define ADD_SET_ERROR(rc, error, count) \ - { \ - (rc) = (error); \ -@@ -1201,7 +1200,7 @@ ldbm_back_add(Slapi_PBlock *pb) - - retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_ADD_FN); - if (retval) { -- set_error(pb, retval, ldap_result_code, &ldap_result_message); -+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message); - goto error_return; - } - -@@ -1471,22 +1470,3 @@ delete_update_entrydn_operational_attributes(struct backentry *ep) - slapi_entry_attr_delete(ep->ep_entry, LDBM_ENTRYDN_STR); - } - --static int --set_error(Slapi_PBlock *pb, int retval, int ldap_result_code, char **ldap_result_message) --{ -- int opreturn = 0; -- if (!ldap_result_code) { -- slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code); -- } -- if (!ldap_result_code) { -- ldap_result_code = LDAP_OPERATIONS_ERROR; -- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); -- } -- slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &opreturn); -- if (!opreturn) { -- slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval); -- } -- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); -- -- return opreturn; --} -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -index db463c18c..be0db1bd0 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -@@ -1276,6 +1276,10 @@ replace_entry: - } - - retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN); -+ if (retval) { -+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message); -+ goto error_return; -+ } - - commit_return: - /* Release SERIAL LOCK */ -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -index 7ee796fd2..cc4319e5f 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c -@@ -867,6 +867,10 @@ ldbm_back_modify(Slapi_PBlock *pb) - goto error_return; - } - retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN); -+ if (retval) { -+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message); -+ goto error_return; -+ } - - /* Release SERIAL LOCK */ - retval = dblayer_txn_commit(be, &txn); -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -index 2c0cb074e..93fb77dc9 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c -@@ -1211,6 +1211,10 @@ ldbm_back_modrdn(Slapi_PBlock *pb) - goto error_return; - } - retval = plugin_call_mmr_plugin_postop(pb, NULL,SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN); -+ if (retval) { -+ ldbm_set_error(pb, retval, &ldap_result_code, &ldap_result_message); -+ goto error_return; -+ } - - /* Release SERIAL LOCK */ - retval = dblayer_txn_commit(be, &txn); -diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c -index df1afdfb1..c52e58a4a 100644 ---- a/ldap/servers/slapd/back-ldbm/misc.c -+++ b/ldap/servers/slapd/back-ldbm/misc.c -@@ -16,6 +16,24 @@ - - #include "back-ldbm.h" - -+void -+ldbm_set_error(Slapi_PBlock *pb, int retval, int *ldap_result_code, char **ldap_result_message) -+{ -+ int opreturn = 0; -+ if (!(*ldap_result_code)) { -+ slapi_pblock_get(pb, SLAPI_RESULT_CODE, ldap_result_code); -+ } -+ if (!(*ldap_result_code)) { -+ *ldap_result_code = LDAP_OPERATIONS_ERROR; -+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, ldap_result_code); -+ } -+ slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &opreturn); -+ if (!opreturn) { -+ slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, *ldap_result_code ? ldap_result_code : &retval); -+ } -+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message); -+} -+ - /* Takes a return code supposed to be errno or from lidb - which we don't expect to see and prints a handy log message */ - void -diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -index 0cee3df62..da3eef18b 100644 ---- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -@@ -379,6 +379,7 @@ int ldbm_txn_ruv_modify_context(Slapi_PBlock *pb, modify_context *mc); - int get_value_from_string(const char *string, char *type, char **value); - int get_values_from_string(const char *string, char *type, char ***valuearray); - void normalize_dir(char *dir); -+void ldbm_set_error(Slapi_PBlock *pb, int retval, int *ldap_result_code, char **ldap_result_message); - - /* - * nextid.c --- -2.13.6 - diff --git a/SOURCES/0047-Ticket-48864-Fix-FreeIPA-build.patch b/SOURCES/0047-Ticket-48864-Fix-FreeIPA-build.patch new file mode 100644 index 0000000..011e441 --- /dev/null +++ b/SOURCES/0047-Ticket-48864-Fix-FreeIPA-build.patch @@ -0,0 +1,46 @@ +From f007ba9e5ac0bbeee1c1d6b4e292b293629a838c Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +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 ++#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 ++#endif + + #ifdef HAVE_INTTYPES_H + #include +-- +2.9.4 + diff --git a/SOURCES/0047-Ticket-49524-Password-policy-minimum-token-length-fa.patch b/SOURCES/0047-Ticket-49524-Password-policy-minimum-token-length-fa.patch deleted file mode 100644 index ee2f366..0000000 --- a/SOURCES/0047-Ticket-49524-Password-policy-minimum-token-length-fa.patch +++ /dev/null @@ -1,133 +0,0 @@ -From a85f64d2c4fa2718748a205d4ae0ebab47513199 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 8 Jan 2018 11:34:02 -0500 -Subject: [PATCH] Ticket 49524 - Password policy: minimum token length fails - when the token length is equal to attribute length - -Bug Description: The token checking breaks when the password is the - exact value of the entry attribute. - -Fix Description: Remove the "equal" part of the string comparisons. - -https://pagure.io/389-ds-base/issue/49524 - -Reviewed by: firstyear & spichugi(Thanks!!) - -(cherry picked from commit 790be09fc434d394239bf2486d01f212b36cf0e3) ---- - .../tests/suites/password/pwdPolicy_token_test.py | 75 ++++++++++++++++++++++ - ldap/servers/slapd/pw.c | 2 +- - ldap/servers/slapd/utf8.c | 2 +- - 3 files changed, 77 insertions(+), 2 deletions(-) - create mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_token_test.py - -diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py -new file mode 100644 -index 000000000..7a4de9c85 ---- /dev/null -+++ b/dirsrvtests/tests/suites/password/pwdPolicy_token_test.py -@@ -0,0 +1,75 @@ -+import logging -+import pytest -+import os -+import time -+import ldap -+from lib389._constants import * -+from lib389.idm.user import UserAccounts -+from lib389.topologies import topology_st as topo -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+USER_DN = 'uid=Test_user1,ou=People,dc=example,dc=com' -+TOKEN = 'test_user1' -+ -+user_properties = { -+ 'uid': 'Test_user1', -+ 'cn': 'test_user1', -+ 'sn': 'test_user1', -+ 'uidNumber': '1001', -+ 'gidNumber': '2001', -+ 'userpassword': PASSWORD, -+ 'description': 'userdesc', -+ 'homeDirectory': '/home/{}'.format('test_user')} -+ -+ -+def pwd_setup(topo): -+ topo.standalone.config.replace_many(('passwordCheckSyntax', 'on'), -+ ('passwordMinLength', '4'), -+ ('passwordMinCategories', '1')) -+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) -+ return users.create(properties=user_properties) -+ -+ -+def test_token_lengths(topo): -+ """Test that password token length is enforced for various lengths including -+ the same length as the attribute being checked by the policy. -+ -+ :id: dae9d916-2a03-4707-b454-9e901d295b13 -+ :setup: Standalone instance -+ :steps: -+ 1. Test token length rejects password of the same length as rdn value -+ :expectedresults: -+ 1. Passwords are rejected -+ """ -+ user = pwd_setup(topo) -+ for length in ['4', '6', '10']: -+ topo.standalone.simple_bind_s(DN_DM, PASSWORD) -+ topo.standalone.config.set('passwordMinTokenLength', length) -+ topo.standalone.simple_bind_s(USER_DN, PASSWORD) -+ time.sleep(1) -+ -+ try: -+ passwd = TOKEN[:int(length)] -+ log.info("Testing password len {} token ({})".format(length, passwd)) -+ user.replace('userpassword', passwd) -+ log.fatal('Password incorrectly allowed!') -+ assert False -+ except ldap.CONSTRAINT_VIOLATION as e: -+ log.info('Password correctly rejected: ' + str(e)) -+ except ldap.LDAPError as e: -+ log.fatal('Unexpected failure ' + str(e)) -+ assert False -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c -index e625962e8..0cf795b41 100644 ---- a/ldap/servers/slapd/pw.c -+++ b/ldap/servers/slapd/pw.c -@@ -1465,7 +1465,7 @@ check_trivial_words(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char * - sp = slapi_ch_strdup(slapi_value_get_string(valp)); - ep = sp + strlen(sp); - ep = ldap_utf8prevn(sp, ep, toklen); -- if (!ep || (sp >= ep)) { -+ if (!ep || (sp > ep)) { - slapi_ch_free_string(&sp); - continue; - } -diff --git a/ldap/servers/slapd/utf8.c b/ldap/servers/slapd/utf8.c -index b0667c636..4538625b3 100644 ---- a/ldap/servers/slapd/utf8.c -+++ b/ldap/servers/slapd/utf8.c -@@ -152,7 +152,7 @@ ldap_utf8prevn(char *s, char *from, int n) - } - for (; n > 0; --n) { - prev = ldap_utf8prev(prev); -- if ((prev <= s) && (n > 0)) { -+ if ((n > 0) && (prev < s)) { - return NULL; - } - } --- -2.13.6 - diff --git a/SOURCES/0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch b/SOURCES/0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch new file mode 100644 index 0000000..c1017a7 --- /dev/null +++ b/SOURCES/0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch @@ -0,0 +1,32 @@ +From 33dc0b3fc6de5d7a400d24a69098ec1b23917e44 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0048-Ticket-49446-cleanallruv-should-ignore-cleaned-repli.patch b/SOURCES/0048-Ticket-49446-cleanallruv-should-ignore-cleaned-repli.patch deleted file mode 100644 index e77d26e..0000000 --- a/SOURCES/0048-Ticket-49446-cleanallruv-should-ignore-cleaned-repli.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7fa2f146c80ed64217bb0c1022c99bd1948cdc7c Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Thu, 11 Jan 2018 15:56:21 +0100 -Subject: [PATCH] Ticket 49446 - cleanallruv should ignore cleaned replica Id - in processing changelog if in force mode - -Bug: If the startcsn is calculated based on a cleaned rid, it could be missing from the changelog. - -Fix: In force mode we do not care that the topology gets in sync for the cleaned RID, so we can ignore it - in an earlier stage, instead of setting it to precleane only. - -Reviewed by: Thierry, thanks ---- - ldap/servers/plugins/replication/repl5_replica_config.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index e025f34d8..005528a41 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -1688,9 +1688,15 @@ replica_cleanallruv_thread(void *arg) - } - /* - * Presetting the rid prevents duplicate thread creation, but allows the db and changelog to still -- * process updates from the rid. set_cleaned_rid() blocks updates, so we don't want to do that... yet. -+ * process updates from the rid. -+ * set_cleaned_rid() blocks updates, so we don't want to do that... yet unless we are in force mode. -+ * If we are forcing a clean independent of state of other servers for this RID we can set_cleaned_rid() - */ -- preset_cleaned_rid(data->rid); -+ if (data->force) { -+ set_cleaned_rid(data->rid); -+ } else { -+ preset_cleaned_rid(data->rid); -+ } - rid_text = slapi_ch_smprintf("%d", data->rid); - csn_as_string(data->maxcsn, PR_FALSE, csnstr); - /* --- -2.13.6 - diff --git a/SOURCES/0049-Ticket-49267-autosize-split-of-0-results-in-dbcache-.patch b/SOURCES/0049-Ticket-49267-autosize-split-of-0-results-in-dbcache-.patch new file mode 100644 index 0000000..7c58465 --- /dev/null +++ b/SOURCES/0049-Ticket-49267-autosize-split-of-0-results-in-dbcache-.patch @@ -0,0 +1,62 @@ +From e52c519a8553dd8abee5740714054ebbdd59e51a Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0049-Ticket-49413-Changelog-trimming-ignores-disabled-rep.patch b/SOURCES/0049-Ticket-49413-Changelog-trimming-ignores-disabled-rep.patch deleted file mode 100644 index bbf059c..0000000 --- a/SOURCES/0049-Ticket-49413-Changelog-trimming-ignores-disabled-rep.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7cb2e56db2da439c90bbfd35f132a85708942490 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Tue, 14 Nov 2017 11:25:18 +0100 -Subject: [PATCH] Ticket 49413 - Changelog trimming ignores disabled - replica-agreement - -Bug: if a replication agreement is disabled it is not taken into account when - changelog trimming determines where to stop. - If the agreement is reenabled later replication can fail - -Fix: do not ignore disabled agreements in changelog trimming - -Reviewed by: Thierry, thanks ---- - ldap/servers/plugins/replication/cl5_api.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index 721013abf..dc2857910 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -4283,12 +4283,10 @@ _cl5GetRUV2Purge2(Object *fileObj, RUV **ruv) - while (agmtObj) { - agmt = (Repl_Agmt *)object_get_data(agmtObj); - PR_ASSERT(agmt); -- -- if (!agmt_is_enabled(agmt)) { -- agmtObj = agmtlist_get_next_agreement_for_replica(r, agmtObj); -- continue; -- } -- -+ /* we need to handle all agreements, also if they are not enabled -+ * if they will be later enabled and changes are trimmed -+ * replication can fail -+ */ - consRUVObj = agmt_get_consumer_ruv(agmt); - if (consRUVObj) { - consRUV = (RUV *)object_get_data(consRUVObj); --- -2.13.6 - diff --git a/SOURCES/0050-Ticket-49231-force-EXTERNAL-always.patch b/SOURCES/0050-Ticket-49231-force-EXTERNAL-always.patch new file mode 100644 index 0000000..685f9ba --- /dev/null +++ b/SOURCES/0050-Ticket-49231-force-EXTERNAL-always.patch @@ -0,0 +1,114 @@ +From d2648bbddbf087c4e3803a89cb67541a50682eae Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0050-Ticket-49278-GetEffectiveRights-gives-false-negative.patch b/SOURCES/0050-Ticket-49278-GetEffectiveRights-gives-false-negative.patch deleted file mode 100644 index f43d383..0000000 --- a/SOURCES/0050-Ticket-49278-GetEffectiveRights-gives-false-negative.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 6e00c3bac13811bc6d94b810b17a59f9428c29f6 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Thu, 11 Jan 2018 15:17:56 +0100 -Subject: [PATCH] Ticket 49278 - GetEffectiveRights gives false-negative - - Bug: If geteffective rights was issued for an non existing entry the - mechanism to genrate a template entry no longer worked and no results were - returned. - Fix: Improve the handling in itreating the result set, so that template entries (if - requested) are genereated and are not applied to existing entries. - Also some code cleanup in iterate() - Reviewed by: Thierry, thanks ---- - ldap/servers/slapd/opshared.c | 239 ++++++++++++++++++++---------------------- - 1 file changed, 114 insertions(+), 125 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 24157120e..46dcf6fba 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -33,6 +33,7 @@ static char *pwpolicy_lock_attrs_all[] = {"passwordRetryCount", - static void compute_limits(Slapi_PBlock *pb); - static int send_results_ext(Slapi_PBlock *pb, int send_result, int *nentries, int pagesize, unsigned int *pr_stat); - static int process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result); -+static void send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries); - - int - op_shared_is_allowed_attr(const char *attr_name, int replicated_op) -@@ -1040,6 +1041,31 @@ process_entry(Slapi_PBlock *pb, Slapi_Entry *e, int send_result) - - return 0; - } -+static void -+send_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Operation *operation, char **attrs, int attrsonly, int *pnentries) -+{ -+ /* -+ * It's a regular entry, or it's a referral and -+ * managedsait control is on. In either case, send -+ * the entry. -+ */ -+ switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { -+ case 0: /* entry sent ok */ -+ (*pnentries)++; -+ slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); -+ break; -+ case 1: /* entry not sent */ -+ break; -+ case -1: /* connection closed */ -+ /* -+ * mark the operation as abandoned so the backend -+ * next entry function gets called again and has -+ * a chance to clean things up. -+ */ -+ operation->o_status = SLAPI_OP_STATUS_ABANDONED; -+ break; -+ } -+} - - #if 0 - /* Loops through search entries and sends them to the client. -@@ -1214,7 +1240,7 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in - *pnentries = 0; - - while (!done) { -- Slapi_Entry *gerentry = NULL; -+ Slapi_Entry *ger_template_entry = NULL; - Slapi_Operation *operation; - - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); -@@ -1236,57 +1262,57 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); - - /* Check for possible get_effective_rights control */ -- if (e) { -- if (operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS) { -- char *errbuf = NULL; -+ if (operation->o_flags & OP_FLAG_GET_EFFECTIVE_RIGHTS) { -+ char *errbuf = NULL; -+ -+ if (PAGEDRESULTS_PAGE_END == pr_stat) { -+ /* -+ * read ahead -- there is at least more entry. -+ * undo it and return the PAGE_END -+ */ -+ be->be_prev_search_results(pb); -+ done = 1; -+ continue; -+ } -+ if ( e == NULL ) { - char **gerattrs = NULL; - char **gerattrsdup = NULL; - char **gap = NULL; - char *gapnext = NULL; -- -- if (PAGEDRESULTS_PAGE_END == pr_stat) { -- /* -- * read ahead -- there is at least more entry. -- * undo it and return the PAGE_END -+ /* we have no more entries -+ * but we might create a template entry for GER -+ * so we need to continue, but make sure to stop -+ * after handling the template entry. -+ * the template entry is a temporary entry returned by the acl -+ * plugin in the pblock and will be freed - */ -- be->be_prev_search_results(pb); -- done = 1; -- continue; -- } -+ done = 1; -+ pr_stat = PAGEDRESULTS_SEARCH_END; - - slapi_pblock_get(pb, SLAPI_SEARCH_GERATTRS, &gerattrs); - gerattrsdup = cool_charray_dup(gerattrs); - gap = gerattrsdup; -- do { -+ while (gap && *gap) { - gapnext = NULL; -- if (gap) { -- if (*gap && *(gap + 1)) { -- gapnext = *(gap + 1); -- *(gap + 1) = NULL; -- } -- slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap); -- rc = plugin_call_acl_plugin(pb, e, attrs, NULL, -- SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, -- &errbuf); -- if (NULL != gapnext) { -- *(gap + 1) = gapnext; -- } -- } else if (NULL != e) { -- rc = plugin_call_acl_plugin(pb, e, attrs, NULL, -- SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, -- &errbuf); -+ if (*(gap + 1)) { -+ gapnext = *(gap + 1); -+ *(gap + 1) = NULL; -+ } -+ slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gap); -+ rc = plugin_call_acl_plugin(pb, e, attrs, NULL, -+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, -+ &errbuf); -+ if (NULL != gapnext) { -+ *(gap + 1) = gapnext; - } -+ gap++; -+ /* get the template entry, if any */ -+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); - if (NULL == e) { -- /* get the template entry, if any */ -- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); -- if (NULL == e) { -- /* everything is ok - don't send the result */ -- pr_stat = PAGEDRESULTS_SEARCH_END; -- done = 1; -- continue; -- } -- gerentry = e; -+ /* everything is ok - don't send the result */ -+ continue; - } -+ ger_template_entry = e; - if (rc != LDAP_SUCCESS) { - /* Send error result and - abort op if the control is critical */ -@@ -1294,65 +1320,53 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in - "Failed to get effective rights for entry (%s), rc=%d\n", - slapi_entry_get_dn_const(e), rc); - send_ldap_result(pb, rc, NULL, errbuf, 0, NULL); -- slapi_ch_free((void **)&errbuf); -- if (gerentry) { -- slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); -- slapi_entry_free(gerentry); -- gerentry = e = NULL; -- } -- pr_stat = PAGEDRESULTS_SEARCH_END; - rval = -1; -- done = 1; -- continue; -- } -- slapi_ch_free((void **)&errbuf); -- if (process_entry(pb, e, send_result)) { -- /* shouldn't send this entry */ -- if (gerentry) { -- slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); -- slapi_entry_free(gerentry); -- gerentry = e = NULL; -+ } else { -+ if (!process_entry(pb, e, send_result)) { -+ /* should send this entry now*/ -+ send_entry(pb, e, operation, attrs, attrsonly, pnentries); - } -- continue; - } - -- /* -- * It's a regular entry, or it's a referral and -- * managedsait control is on. In either case, send -- * the entry. -- */ -- switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { -- case 0: /* entry sent ok */ -- (*pnentries)++; -- slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); -- break; -- case 1: /* entry not sent */ -- break; -- case -1: /* connection closed */ -- /* -- * mark the operation as abandoned so the backend -- * next entry function gets called again and has -- * a chance to clean things up. -- */ -- operation->o_status = SLAPI_OP_STATUS_ABANDONED; -- break; -- } -- if (gerentry) { -+ slapi_ch_free((void **)&errbuf); -+ if (ger_template_entry) { - slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, NULL); -- slapi_entry_free(gerentry); -- gerentry = e = NULL; -+ slapi_entry_free(ger_template_entry); -+ ger_template_entry = e = NULL; - } -- } while (gap && ++gap && *gap); -+ } /* while ger template */ - slapi_pblock_set(pb, SLAPI_SEARCH_GERATTRS, gerattrs); - cool_charray_free(gerattrsdup); -- if (pagesize == *pnentries) { -- /* PAGED RESULTS: reached the pagesize */ -- /* We don't set "done = 1" here. -- * We read ahead next entry to check whether there is -- * more entries to return or not. */ -- pr_stat = PAGEDRESULTS_PAGE_END; -+ } else { -+ /* we are processing geteffective rights for an existing entry */ -+ rc = plugin_call_acl_plugin(pb, e, attrs, NULL, -+ SLAPI_ACL_ALL, ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS, -+ &errbuf); -+ if (rc != LDAP_SUCCESS) { -+ /* Send error result and -+ abort op if the control is critical */ -+ slapi_log_err(SLAPI_LOG_ERR, "iterate", -+ "Failed to get effective rights for entry (%s), rc=%d\n", -+ slapi_entry_get_dn_const(e), rc); -+ send_ldap_result(pb, rc, NULL, errbuf, 0, NULL); -+ rval = -1; -+ } else { -+ if (!process_entry(pb, e, send_result)) { -+ /* should send this entry now*/ -+ send_entry(pb, e, operation, attrs, attrsonly, pnentries); -+ if (pagesize == *pnentries) { -+ /* PAGED RESULTS: reached the pagesize */ -+ /* We don't set "done = 1" here. -+ * We read ahead next entry to check whether there is -+ * more entries to return or not. */ -+ pr_stat = PAGEDRESULTS_PAGE_END; -+ } -+ } - } -- } else { /* not GET_EFFECTIVE_RIGHTS */ -+ slapi_ch_free((void **)&errbuf); -+ } -+ /* not GET_EFFECTIVE_RIGHTS */ -+ } else if (e) { - if (PAGEDRESULTS_PAGE_END == pr_stat) { - /* - * read ahead -- there is at least more entry. -@@ -1364,46 +1378,21 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result, int *pnentries, in - } - /* Adding shadow password attrs. */ - add_shadow_ext_password_attrs(pb, &e); -- if (process_entry(pb, e, send_result)) { -- /* shouldn't send this entry */ -- struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb); -- slapi_entry_free(pb_pw_entry); -- slapi_pblock_set_pw_entry(pb, NULL); -- continue; -- } -- -- /* -- * It's a regular entry, or it's a referral and -- * managedsait control is on. In either case, send -- * the entry. -- */ -- switch (send_ldap_search_entry(pb, e, NULL, attrs, attrsonly)) { -- case 0: /* entry sent ok */ -- (*pnentries)++; -- slapi_pblock_set(pb, SLAPI_NENTRIES, pnentries); -- break; -- case 1: /* entry not sent */ -- break; -- case -1: /* connection closed */ -- /* -- * mark the operation as abandoned so the backend -- * next entry function gets called again and has -- * a chance to clean things up. -- */ -- operation->o_status = SLAPI_OP_STATUS_ABANDONED; -- break; -+ if (!process_entry(pb, e, send_result)) { -+ /*this entry was not sent, do it now*/ -+ send_entry(pb, e, operation, attrs, attrsonly, pnentries); -+ if (pagesize == *pnentries) { -+ /* PAGED RESULTS: reached the pagesize */ -+ /* We don't set "done = 1" here. -+ * We read ahead next entry to check whether there is -+ * more entries to return or not. */ -+ pr_stat = PAGEDRESULTS_PAGE_END; -+ } - } -+ /* cleanup pw entry . sent or not */ - struct slapi_entry *pb_pw_entry = slapi_pblock_get_pw_entry(pb); - slapi_entry_free(pb_pw_entry); - slapi_pblock_set_pw_entry(pb, NULL); -- if (pagesize == *pnentries) { -- /* PAGED RESULTS: reached the pagesize */ -- /* We don't set "done = 1" here. -- * We read ahead next entry to check whether there is -- * more entries to return or not. */ -- pr_stat = PAGEDRESULTS_PAGE_END; -- } -- } - } else { - /* no more entries */ - done = 1; --- -2.13.6 - diff --git a/SOURCES/0051-Ticket-48538-Failed-to-delete-old-semaphore.patch b/SOURCES/0051-Ticket-48538-Failed-to-delete-old-semaphore.patch new file mode 100644 index 0000000..4d2d345 --- /dev/null +++ b/SOURCES/0051-Ticket-48538-Failed-to-delete-old-semaphore.patch @@ -0,0 +1,58 @@ +From bbc63ef4dab6c275b1d8b8fe6439483309781401 Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0051-Ticket-49531-coverity-issues-fix-memory-leaks.patch b/SOURCES/0051-Ticket-49531-coverity-issues-fix-memory-leaks.patch deleted file mode 100644 index b264ff5..0000000 --- a/SOURCES/0051-Ticket-49531-coverity-issues-fix-memory-leaks.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 7acfb18228322ab2e331720bd7fe083da04625a2 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 12 Jan 2018 09:50:34 -0500 -Subject: [PATCH] Ticket 49531 - coverity issues - fix memory leaks - -Description: There were two false positives around pwpolicy struct - being leaked, but it is freed when the pblock is - destroyed. The other two leaks were real, but they - only occurred during error conditions. - -https://pagure.io/389-ds-base/issue/49531 - -Reviewed by: lkrispen (Thanks!) - -(cherry picked from commit 700d7422e6309d2d405961abbb805fbfe852e53c) ---- - ldap/servers/plugins/replication/cl5_api.c | 1 + - ldap/servers/plugins/replication/urp.c | 3 ++- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index dc2857910..89ae9956c 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -4046,6 +4046,7 @@ _cl5WriteRUV(CL5DBFile *file, PRBool purge) - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, - "_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n", - file->name); -+ ber_bvecfree(vals); - return CL5_DB_ERROR; - } - -diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c -index 9534c0322..d4556d7fd 100644 ---- a/ldap/servers/plugins/replication/urp.c -+++ b/ldap/servers/plugins/replication/urp.c -@@ -861,7 +861,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - Slapi_Entry *pre_entry = NULL; - int ret = 0; - Slapi_DN *pre_sdn = NULL; -- Slapi_RDN *rdn = slapi_rdn_new(); -+ Slapi_RDN *rdn = NULL; - char *parentdn = NULL; - char *newdn; - const char *entrydn; -@@ -882,6 +882,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - entrydn = slapi_entry_get_ndn (pre_entry);*/ - uniqueid = slapi_entry_get_uniqueid (pre_entry); - parentdn = slapi_dn_parent(entrydn); -+ rdn = slapi_rdn_new(); - slapi_sdn_get_rdn(pre_sdn, rdn); - slapi_rdn_remove_attr (rdn, SLAPI_ATTR_UNIQUEID ); - slapi_rdn_add(rdn, "cenotaphID", uniqueid); --- -2.13.6 - diff --git a/SOURCES/0052-Ticket-49257-Reject-nsslapd-cachememsize-nsslapd-cac.patch b/SOURCES/0052-Ticket-49257-Reject-nsslapd-cachememsize-nsslapd-cac.patch new file mode 100644 index 0000000..b75d574 --- /dev/null +++ b/SOURCES/0052-Ticket-49257-Reject-nsslapd-cachememsize-nsslapd-cac.patch @@ -0,0 +1,131 @@ +From 0f04c8e7c1219940baf0ae9c1bcb2464ddf079df Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0052-Ticket-49529-Fix-Coverity-warnings-invalid-deference.patch b/SOURCES/0052-Ticket-49529-Fix-Coverity-warnings-invalid-deference.patch deleted file mode 100644 index 1d91b81..0000000 --- a/SOURCES/0052-Ticket-49529-Fix-Coverity-warnings-invalid-deference.patch +++ /dev/null @@ -1,503 +0,0 @@ -From 0b5cbcf45f3fb4b03a1f762c5704183787d30696 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 12 Jan 2018 08:38:22 -0500 -Subject: [PATCH] Ticket 49529 - Fix Coverity warnings: invalid deferences - -Description: So many of the warnings were false positives, but - I "fixed" 90% of them anyway for these two reasons: - - One, it's possible that a future change could actually - result in a NULL pointer being referenced. - - Two, it would be nice to stop these coverity warnings - so we can focus on real warnings. Auto waivers also - don't always work as the surrounding code changes. - -https://pagure.io/389-ds-base/issue/49529 - -Reviewed by: firstyear (Thanks!) - -(cherry picked from commit 7e27face5ef021d883a44d70bb3e9732b115016f) ---- - ldap/servers/slapd/abandon.c | 10 ++++++++-- - ldap/servers/slapd/add.c | 18 +++++++++++++++--- - ldap/servers/slapd/bind.c | 20 +++++++++++++++----- - ldap/servers/slapd/compare.c | 17 +++++++++++++---- - ldap/servers/slapd/connection.c | 19 +++++++++++++------ - ldap/servers/slapd/delete.c | 4 ++-- - ldap/servers/slapd/dn.c | 7 +++++++ - ldap/servers/slapd/entry.c | 10 +++++++++- - ldap/servers/slapd/extendop.c | 7 +++++++ - ldap/servers/slapd/filter.c | 6 +++++- - ldap/servers/slapd/modify.c | 18 ++++++++++++++++-- - ldap/servers/slapd/passwd_extop.c | 4 ++++ - ldap/servers/slapd/psearch.c | 13 +++++++++---- - ldap/servers/slapd/result.c | 14 +++++++++++++- - ldap/servers/slapd/search.c | 5 ++++- - ldap/servers/slapd/task.c | 5 +++++ - 16 files changed, 145 insertions(+), 32 deletions(-) - -diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c -index 5c30c972d..e2237e5fc 100644 ---- a/ldap/servers/slapd/abandon.c -+++ b/ldap/servers/slapd/abandon.c -@@ -42,10 +42,16 @@ do_abandon(Slapi_PBlock *pb) - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - -- BerElement *ber = pb_op->o_ber; -- - slapi_log_err(SLAPI_LOG_TRACE, "do_abandon", "->\n"); - -+ if (pb_op == NULL || pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "do_abandon", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n", -+ pb_conn, pb_op); -+ return; -+ } -+ -+ BerElement *ber = pb_op->o_ber; -+ - /* - * Parse the abandon request. It looks like this: - * -diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c -index 0a4a5d7b2..8f2fdeac8 100644 ---- a/ldap/servers/slapd/add.c -+++ b/ldap/servers/slapd/add.c -@@ -66,6 +66,14 @@ do_add(Slapi_PBlock *pb) - - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); -+ -+ -+ if (operation == NULL || pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "do_add", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n", -+ pb_conn, operation); -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL); -+ return; -+ } - ber = operation->o_ber; - - /* count the add request */ -@@ -450,8 +458,8 @@ op_shared_add(Slapi_PBlock *pb) - - if (!internal_op) { - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d ADD dn=\"%s\"%s\n", -- pb_conn->c_connid, -- operation->o_opid, -+ pb_conn ? pb_conn->c_connid : -1, -+ operation ? operation->o_opid: -1, - slapi_entry_get_dn_const(e), - proxystr ? proxystr : ""); - } else { -@@ -865,7 +873,11 @@ handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry) - int ret; - - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- -+ if (pb_conn == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "handle_fast_add", "NULL param: pb_conn (0x%p)\n", pb_conn); -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL); -+ return; -+ } - be = pb_conn->c_bi_backend; - - if ((be == NULL) || (be->be_wire_import == NULL)) { -diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c -index 4a8e4deaf..a34a21a77 100644 ---- a/ldap/servers/slapd/bind.c -+++ b/ldap/servers/slapd/bind.c -@@ -54,11 +54,7 @@ do_bind(Slapi_PBlock *pb) - { - Operation *pb_op = NULL; - Connection *pb_conn = NULL; -- -- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- -- BerElement *ber = pb_op->o_ber; -+ BerElement *ber; - int err, isroot; - ber_tag_t method = LBER_DEFAULT; - ber_int_t version = -1; -@@ -83,6 +79,16 @@ do_bind(Slapi_PBlock *pb) - - slapi_log_err(SLAPI_LOG_TRACE, "do_bind", "=>\n"); - -+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (pb_op == NULL || pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "do_bind", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n", -+ pb_conn, pb_op); -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); -+ goto free_and_return; -+ } -+ ber = pb_op->o_ber; -+ - /* - * Parse the bind request. It looks like this: - * -@@ -856,6 +862,10 @@ log_bind_access( - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - -+ if (pb_op == NULL || pb_conn == NULL) { -+ return; -+ } -+ - if (method == LDAP_AUTH_SASL && saslmech && msg) { - slapi_log_access(LDAP_DEBUG_STATS, - "conn=%" PRIu64 " op=%d BIND dn=\"%s\" " -diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c -index 9bc6b693a..2626d91d0 100644 ---- a/ldap/servers/slapd/compare.c -+++ b/ldap/servers/slapd/compare.c -@@ -35,10 +35,7 @@ do_compare(Slapi_PBlock *pb) - { - Operation *pb_op = NULL; - Connection *pb_conn = NULL; -- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- -- BerElement *ber = pb_op->o_ber; -+ BerElement *ber; - char *rawdn = NULL; - const char *dn = NULL; - struct ava ava = {0}; -@@ -50,6 +47,18 @@ do_compare(Slapi_PBlock *pb) - - slapi_log_err(SLAPI_LOG_TRACE, "do_compare", "=>\n"); - -+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ -+ if (pb_op == NULL || pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "do_compare", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n", -+ pb_conn, pb_op); -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); -+ goto free_and_return; -+ } -+ -+ ber = pb_op->o_ber; -+ - /* count the compare request */ - slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); - -diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c -index 8ef115691..fa24ec040 100644 ---- a/ldap/servers/slapd/connection.c -+++ b/ldap/servers/slapd/connection.c -@@ -1518,7 +1518,7 @@ connection_threadmain() - } - - if (!thread_turbo_flag && !more_data) { -- Connection *pb_conn = NULL; -+ Connection *pb_conn = NULL; - - /* If more data is left from the previous connection_read_operation, - we should finish the op now. Client might be thinking it's -@@ -1530,6 +1530,13 @@ connection_threadmain() - * Connection wait for new work provides the conn and op for us. - */ - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", -+ "pb_conn is NULL\n"); -+ slapi_pblock_destroy(pb); -+ g_decr_active_threadcnt(); -+ return; -+ } - - switch (ret) { - case CONN_NOWORK: -@@ -1702,11 +1709,11 @@ connection_threadmain() - * so need locking from here on */ - signal_listner(); - /* with nunc-stans, I see an enormous amount of time spent in the poll() in -- * connection_read_operation() when the below code is enabled - not sure why -- * nunc-stans makes such a huge difference - for now, just disable this code -- * when using nunc-stans - it is supposed to be an optimization but turns out -- * to not be the opposite with nunc-stans -- */ -+ * connection_read_operation() when the below code is enabled - not sure why -+ * nunc-stans makes such a huge difference - for now, just disable this code -+ * when using nunc-stans - it is supposed to be an optimization but turns out -+ * to not be the opposite with nunc-stans -+ */ - } else if (!enable_nunc_stans) { /* more data in conn - just put back on work_q - bypass poll */ - bypasspollcnt++; - PR_EnterMonitor(conn->c_mutex); -diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c -index ba238b18f..49cdab138 100644 ---- a/ldap/servers/slapd/delete.c -+++ b/ldap/servers/slapd/delete.c -@@ -262,8 +262,8 @@ op_shared_delete(Slapi_PBlock *pb) - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d DEL dn=\"%s\"%s\n", -- pb_conn->c_connid, -- pb_op->o_opid, -+ pb_conn ? pb_conn->c_connid : -1, -+ pb_op ? pb_op->o_opid : -1, - slapi_sdn_get_dn(sdn), - proxystr ? proxystr : ""); - } else { -diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c -index afca37214..abc155533 100644 ---- a/ldap/servers/slapd/dn.c -+++ b/ldap/servers/slapd/dn.c -@@ -2477,6 +2477,13 @@ slapi_sdn_copy(const Slapi_DN *from, Slapi_DN *to) - { - SDN_DUMP(from, "slapi_sdn_copy from"); - SDN_DUMP(to, "slapi_sdn_copy to"); -+ -+ if (to == NULL || from == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "slapi_sdn_copy", -+ "NULL param: from (0x%p) to (0x%p)\n", from, to); -+ return; -+ } -+ - slapi_sdn_done(to); - if (from->udn) { - to->flag = slapi_setbit_uchar(to->flag, FLAG_UDN); -diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c -index fbbc8faa0..32828b4e2 100644 ---- a/ldap/servers/slapd/entry.c -+++ b/ldap/servers/slapd/entry.c -@@ -1998,6 +1998,10 @@ slapi_entry_dup(const Slapi_Entry *e) - struct attrs_in_extension *aiep; - - PR_ASSERT(NULL != e); -+ if (e == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "slapi_entry_dup", "entry is NULL\n"); -+ return NULL; -+ } - - ec = slapi_entry_alloc(); - -@@ -3660,7 +3664,11 @@ delete_values_sv_internal( - Slapi_Attr *a; - int retVal = LDAP_SUCCESS; - --/* -+ if (e == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "delete_values_sv_internal", "entry is NULL\n"); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ /* - * If type is in the protected_attrs_all list, we could ignore the failure, - * as the attribute could only exist in the entry in the memory when the - * add/mod operation is done, while the retried entry from the db does not -diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c -index 1594a8c9c..815949be6 100644 ---- a/ldap/servers/slapd/extendop.c -+++ b/ldap/servers/slapd/extendop.c -@@ -219,6 +219,13 @@ do_extended(Slapi_PBlock *pb) - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - -+ if (pb_conn == NULL || pb_op == NULL) { -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "param error", 0, NULL); -+ slapi_log_err(SLAPI_LOG_ERR, "do_extended", -+ "NULL param error: conn (0x%p) op (0x%p)\n", pb_conn, pb_op); -+ goto free_and_return; -+ } -+ - /* - * Parse the extended request. It looks like this: - * -diff --git a/ldap/servers/slapd/filter.c b/ldap/servers/slapd/filter.c -index fe3525f34..ef975e679 100644 ---- a/ldap/servers/slapd/filter.c -+++ b/ldap/servers/slapd/filter.c -@@ -292,7 +292,11 @@ get_filter_internal(Connection *conn, BerElement *ber, struct slapi_filter **fil - - case LDAP_FILTER_EXTENDED: - slapi_log_err(SLAPI_LOG_FILTER, "get_filter_internal", "EXTENDED\n"); -- if (conn->c_ldapversion < 3) { -+ if (conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "get_filter_internal", -+ "NULL param: conn (0x%p)\n", conn); -+ err = LDAP_OPERATIONS_ERROR; -+ } else if (conn->c_ldapversion < 3) { - slapi_log_err(SLAPI_LOG_ERR, "get_filter_internal", - "Extensible filter received from v2 client\n"); - err = LDAP_PROTOCOL_ERROR; -diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c -index 0dcac646b..10d263159 100644 ---- a/ldap/servers/slapd/modify.c -+++ b/ldap/servers/slapd/modify.c -@@ -122,9 +122,16 @@ do_modify(Slapi_PBlock *pb) - slapi_log_err(SLAPI_LOG_TRACE, "do_modify", "=>\n"); - - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); -- ber = operation->o_ber; -- - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (operation == NULL) { -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, -+ NULL, "operation is NULL parameter", 0, NULL); -+ slapi_log_err(SLAPI_LOG_ERR, "do_modify", -+ "NULL param: pb_conn (0x%p) operation (0x%p)\n", pb_conn, operation); -+ return; -+ } -+ -+ ber = operation->o_ber; - - /* count the modify request */ - slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyEntryOps); -@@ -1165,6 +1172,13 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - -+ if (pb_conn == NULL || operation == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "op_shared_allow_pw_change", -+ "NULL param error: conn (0x%p) op (0x%p)\n", pb_conn, operation); -+ rc = -1; -+ goto done; -+ } -+ - slapi_sdn_init_dn_byref(&sdn, dn); - pwpolicy = new_passwdPolicy(pb, (char *)slapi_sdn_get_ndn(&sdn)); - -diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c -index 54a9a6716..40145af2e 100644 ---- a/ldap/servers/slapd/passwd_extop.c -+++ b/ldap/servers/slapd/passwd_extop.c -@@ -486,6 +486,10 @@ passwd_modify_extop(Slapi_PBlock *pb) - /* Allow password modify only for SSL/TLS established connections and - * connections using SASL privacy layers */ - slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); -+ if (conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "conn is NULL"); -+ goto free_and_return; -+ } - if (slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) { - errMesg = "Could not get SASL SSF from connection\n"; - rc = LDAP_OPERATIONS_ERROR; -diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c -index e0dd2bf89..1bf062954 100644 ---- a/ldap/servers/slapd/psearch.c -+++ b/ldap/servers/slapd/psearch.c -@@ -271,6 +271,11 @@ ps_send_results(void *arg) - slapi_pblock_get(ps->ps_pblock, SLAPI_CONNECTION, &pb_conn); - slapi_pblock_get(ps->ps_pblock, SLAPI_OPERATION, &pb_op); - -+ if (pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "ps_send_results", "pb_conn is NULL\n"); -+ return; -+ } -+ - /* need to acquire a reference to this connection so that it will not - be released or cleaned up out from under us */ - PR_EnterMonitor(pb_conn->c_mutex); -@@ -280,7 +285,7 @@ ps_send_results(void *arg) - if (conn_acq_flag) { - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", - "conn=%" PRIu64 " op=%d Could not acquire the connection - psearch aborted\n", -- pb_conn->c_connid, pb_op->o_opid); -+ pb_conn->c_connid, pb_op ? pb_op->o_opid : -1); - } - - PR_Lock(psearch_list->pl_cvarlock); -@@ -290,7 +295,7 @@ ps_send_results(void *arg) - if (pb_op == NULL || slapi_op_abandoned(ps->ps_pblock)) { - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", - "conn=%" PRIu64 " op=%d The operation has been abandoned\n", -- pb_conn->c_connid, pb_op->o_opid); -+ pb_conn->c_connid, pb_op ? pb_op->o_opid : -1); - break; - } - if (NULL == ps->ps_eq_head) { -@@ -532,7 +537,7 @@ ps_service_persistent_searches(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chg - slapi_log_err(SLAPI_LOG_CONNS, "ps_service_persistent_searches", - "conn=%" PRIu64 " op=%d entry %s with chgtype %d " - "matches the ps changetype %d\n", -- pb_conn->c_connid, -+ pb_conn ? pb_conn->c_connid : -1, - pb_op->o_opid, - edn, chgtype, ps->ps_changetypes); - -@@ -609,7 +614,7 @@ ps_service_persistent_searches(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chg - /* Turn 'em loose */ - ps_wakeup_all(); - slapi_log_err(SLAPI_LOG_TRACE, "ps_service_persistent_searches", "Enqueued entry " -- "\"%s\" on %d persistent search lists\n", -+ "\"%s\" on %d persistent search lists\n", - slapi_entry_get_dn_const(e), matched); - } else { - slapi_log_err(SLAPI_LOG_TRACE, "ps_service_persistent_searches", -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index 2302ae96b..ce394d948 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -396,7 +396,7 @@ send_ldap_result_ext( - break; - - case LDAP_REFERRAL: -- if (conn->c_ldapversion > LDAP_VERSION2) { -+ if (conn && conn->c_ldapversion > LDAP_VERSION2) { - tag = LDAP_TAG_REFERRAL; - break; - } -@@ -645,6 +645,11 @@ process_read_entry_controls(Slapi_PBlock *pb, char *oid) - BerElement *req_ber = NULL; - Operation *op = NULL; - slapi_pblock_get(pb, SLAPI_OPERATION, &op); -+ if (op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "process_read_entry_controls", "op is NULL\n"); -+ rc = -1; -+ goto done; -+ } - - if (strcmp(oid, LDAP_CONTROL_PRE_READ_ENTRY) == 0) { - /* first verify this is the correct operation for a pre-read entry control */ -@@ -2145,6 +2150,13 @@ encode_read_entry(Slapi_PBlock *pb, Slapi_Entry *e, char **attrs, int alluseratt - slapi_pblock_get(pb, SLAPI_OPERATION, &op); - slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); - -+ if (conn == NULL || op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "encode_read_entry", -+ "NULL param error: conn (0x%p) op (0x%p)\n", conn, op); -+ rc = -1; -+ goto cleanup; -+ } -+ - /* Start the ber encoding with the DN */ - rc = ber_printf(ber, "t{s{", LDAP_RES_SEARCH_ENTRY, slapi_entry_get_dn_const(e)); - if (rc == -1) { -diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c -index 5e3413245..731c6519e 100644 ---- a/ldap/servers/slapd/search.c -+++ b/ldap/servers/slapd/search.c -@@ -125,7 +125,10 @@ do_search(Slapi_PBlock *pb) - goto free_and_return; - } - -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn) != 0 || pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "do_search", "pb_conn is NULL\n"); -+ goto free_and_return; -+ } - - /* - * If nsslapd-minssf-exclude-rootdse is on, the minssf check has been -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 53a0af52d..002083c04 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -199,6 +199,11 @@ slapi_task_log_status(Slapi_Task *task, char *format, ...) - { - va_list ap; - -+ if (task == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "slapi_task_log_status", -+ "Slapi_Task is NULL, can not log status\n"); -+ return; -+ } - if (!task->task_status) - task->task_status = (char *)slapi_ch_malloc(10 * LOG_BUFFER); - if (!task->task_status) --- -2.13.6 - diff --git a/SOURCES/0053-Ticket-49257-Reject-dbcachesize-updates-while-auto-c.patch b/SOURCES/0053-Ticket-49257-Reject-dbcachesize-updates-while-auto-c.patch new file mode 100644 index 0000000..de2e652 --- /dev/null +++ b/SOURCES/0053-Ticket-49257-Reject-dbcachesize-updates-while-auto-c.patch @@ -0,0 +1,53 @@ +From 550d30d3aa27cd69057604e1ee7d5ca43711d718 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0053-Ticket-49463-After-cleanALLruv-there-is-a-flow-of-ke.patch b/SOURCES/0053-Ticket-49463-After-cleanALLruv-there-is-a-flow-of-ke.patch deleted file mode 100644 index c0f08f7..0000000 --- a/SOURCES/0053-Ticket-49463-After-cleanALLruv-there-is-a-flow-of-ke.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 0ac68e15a9a4048d3c1ad4519000996cd65fdefb Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Fri, 1 Dec 2017 16:23:11 +0100 -Subject: [PATCH] Ticket 49463 - After cleanALLruv, there is a flow of keep - alive DEL - -Bug Description: - When cleanAllRuv is launched, it spawn cleanAllRuv on all replicas. - Each replica will clean its changelog and database RUV AND in addition - will DEL the keep alive entry of the target ReplicaID. - So for the same entry (keep alive) there will be as many DEL as there are replicas - - This flow of DEL is useless as only one DEL is enough. - In addition because of https://pagure.io/389-ds-base/issue/49466, replication may - loop on each of those DELs. - -Fix Description: - The fix is only to prevent the flow of DEL. - It adds a flag ('original_task') in the task payload. - The server receiving the task (replica_execute_cleanall_ruv_task) flags the - task as 'original_task'. - In the opposite, the propagated cleanAllRuv (multimaster_extop_cleanruv) does - not flag the task as 'original_task' - Only original task does the DEL of the keep alive entry. - Note the propageted payload (extop) is not changed. In a mixed version - environment "old" servers will DEL the keep alive and flow can still happen - -https://pagure.io/389-ds-base/issue/49466 - -Reviewed by: Ludwig Krispenz - -Platforms tested: F23 - -Flag Day: no - -Doc impact: no ---- - ldap/servers/plugins/replication/repl5.h | 49 ++++++++++++---------- - ldap/servers/plugins/replication/repl5_replica.c | 21 ++++++++++ - .../plugins/replication/repl5_replica_config.c | 32 +++++++++++--- - ldap/servers/plugins/replication/repl_extop.c | 2 + - 4 files changed, 76 insertions(+), 28 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h -index 4e206a0fc..e08fec752 100644 ---- a/ldap/servers/plugins/replication/repl5.h -+++ b/ldap/servers/plugins/replication/repl5.h -@@ -783,12 +783,37 @@ void multimaster_mtnode_construct_replicas(void); - - void multimaster_be_state_change(void *handle, char *be_name, int old_be_state, int new_be_state); - -+#define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */ -+ -+typedef struct _cleanruv_data -+{ -+ Object *repl_obj; -+ Replica *replica; -+ ReplicaId rid; -+ Slapi_Task *task; -+ struct berval *payload; -+ CSN *maxcsn; -+ char *repl_root; -+ Slapi_DN *sdn; -+ char *certify; -+ char *force; -+ PRBool original_task; -+} cleanruv_data; -+ -+typedef struct _cleanruv_purge_data -+{ -+ int cleaned_rid; -+ const Slapi_DN *suffix_sdn; -+ char *replName; -+ char *replGen; -+} cleanruv_purge_data; -+ - /* In repl5_replica_config.c */ - int replica_config_init(void); - void replica_config_destroy(void); - int get_replica_type(Replica *r); - int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid); --void add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing); -+void add_cleaned_rid(cleanruv_data *data, char *maxcsn); - int is_cleaned_rid(ReplicaId rid); - int replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); - void replica_cleanallruv_thread_ext(void *arg); -@@ -808,29 +833,7 @@ void set_cleaned_rid(ReplicaId rid); - void cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...); - char *replica_cleanallruv_get_local_maxcsn(ReplicaId rid, char *base_dn); - --#define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */ - --typedef struct _cleanruv_data --{ -- Object *repl_obj; -- Replica *replica; -- ReplicaId rid; -- Slapi_Task *task; -- struct berval *payload; -- CSN *maxcsn; -- char *repl_root; -- Slapi_DN *sdn; -- char *certify; -- char *force; --} cleanruv_data; -- --typedef struct _cleanruv_purge_data --{ -- int cleaned_rid; -- const Slapi_DN *suffix_sdn; -- char *replName; -- char *replGen; --} cleanruv_purge_data; - - /* replutil.c */ - LDAPControl *create_managedsait_control(void); -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index 77f4f18e4..e75807a62 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -2120,6 +2120,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e) - char csnstr[CSN_STRSIZE]; - char *token = NULL; - char *forcing; -+ PRBool original_task; - char *csnpart; - char *ridstr; - char *iter = NULL; -@@ -2151,8 +2152,15 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e) - csn_init_by_string(maxcsn, csnpart); - csn_as_string(maxcsn, PR_FALSE, csnstr); - forcing = ldap_utf8strtok_r(iter, ":", &iter); -+ original_task = PR_TRUE; - if (forcing == NULL) { - forcing = "no"; -+ } else if (!strcasecmp(forcing, "yes") || !strcasecmp(forcing, "no")) { -+ /* forcing was correctly set, lets try to read the original task flag */ -+ token = ldap_utf8strtok_r(iter, ":", &iter); -+ if (token && !atoi(token)) { -+ original_task = PR_FALSE; -+ } - } - - slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name, "CleanAllRUV Task - cleanAllRUV task found, " -@@ -2190,6 +2198,13 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e) - data->force = slapi_ch_strdup(forcing); - data->repl_root = NULL; - -+ /* This is a corner case, a cleanAllRuv task was interrupted by a shutdown or a crash -+ * We retrieved from type_replicaCleanRUV if the cleanAllRuv request -+ * was received from a direct task ADD or if was received via -+ * the cleanAllRuv extop. -+ */ -+ data->original_task = original_task; -+ - thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext, - (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); -@@ -2284,6 +2299,12 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e) - data->sdn = slapi_sdn_dup(r->repl_root); - data->certify = slapi_ch_strdup(certify); - -+ /* This is a corner case, a cleanAllRuv task was interrupted by a shutdown or a crash -+ * Let's assum this replica was the original receiver of the task. -+ * This flag has no impact on Abort cleanAllRuv -+ */ -+ data->original_task = PR_TRUE; -+ - thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread, - (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 005528a41..95b933bb8 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -1573,6 +1573,11 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co - data->repl_root = slapi_ch_strdup(basedn); - data->force = slapi_ch_strdup(force_cleaning); - -+ /* It is either a consequence of a direct ADD cleanAllRuv task -+ * or modify of the replica to add nsds5task: cleanAllRuv -+ */ -+ data->original_task = PR_TRUE; -+ - thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread, - (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); -@@ -1702,7 +1707,7 @@ replica_cleanallruv_thread(void *arg) - /* - * Add the cleanallruv task to the repl config - so we can handle restarts - */ -- add_cleaned_rid(data->rid, data->replica, csnstr, data->force); /* marks config that we started cleaning a rid */ -+ add_cleaned_rid(data, csnstr); /* marks config that we started cleaning a rid */ - cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Cleaning rid (%d)...", data->rid); - /* - * First, wait for the maxcsn to be covered -@@ -1878,7 +1883,13 @@ done: - */ - delete_cleaned_rid_config(data); - check_replicas_are_done_cleaning(data); -- remove_keep_alive_entry(data->task, data->rid, data->repl_root); -+ if (data->original_task) { -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Original task deletes Keep alive entry (%d).", data->rid); -+ remove_keep_alive_entry(data->task, data->rid, data->repl_root); -+ } else { -+ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Propagated task does not delete Keep alive entry (%d).", data->rid); -+ } -+ - clean_agmts(data); - remove_cleaned_rid(data->rid); - cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d).", data->rid); -@@ -2029,7 +2040,7 @@ check_replicas_are_done_cleaning(cleanruv_data *data) - "Waiting for all the replicas to finish cleaning..."); - - csn_as_string(data->maxcsn, PR_FALSE, csnstr); -- filter = PR_smprintf("(%s=%d:%s:%s)", type_replicaCleanRUV, (int)data->rid, csnstr, data->force); -+ filter = PR_smprintf("(%s=%d:%s:%s:%d)", type_replicaCleanRUV, (int)data->rid, csnstr, data->force, data->original_task ? 1 : 0); - while (not_all_cleaned && !is_task_aborted(data->rid) && !slapi_is_shutting_down()) { - agmt_obj = agmtlist_get_first_agreement_for_replica(data->replica); - if (agmt_obj == NULL) { -@@ -2502,7 +2513,7 @@ set_cleaned_rid(ReplicaId rid) - * Add the rid and maxcsn to the repl config (so we can resume after a server restart) - */ - void --add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing) -+add_cleaned_rid(cleanruv_data *cleanruv_data, char *maxcsn) - { - Slapi_PBlock *pb; - struct berval *vals[2]; -@@ -2512,6 +2523,16 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing) - char data[CSN_STRSIZE + 10]; - char *dn; - int rc; -+ ReplicaId rid; -+ Replica *r; -+ char *forcing; -+ -+ if (data == NULL) { -+ return; -+ } -+ rid = cleanruv_data->rid; -+ r = cleanruv_data->replica; -+ forcing = cleanruv_data->force; - - if (r == NULL || maxcsn == NULL) { - return; -@@ -2519,7 +2540,7 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn, char *forcing) - /* - * Write the rid & maxcsn to the config entry - */ -- val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s", rid, maxcsn, forcing); -+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s:%d", rid, maxcsn, forcing, cleanruv_data->original_task ? 1 : 0); - dn = replica_get_dn(r); - pb = slapi_pblock_new(); - mod.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; -@@ -2961,6 +2982,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), - data->repl_root = slapi_ch_strdup(base_dn); - data->sdn = NULL; - data->certify = slapi_ch_strdup(certify_all); -+ data->original_task = PR_TRUE; - - thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread, - (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, -diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c -index c49c6bd8d..68e2544b4 100644 ---- a/ldap/servers/plugins/replication/repl_extop.c -+++ b/ldap/servers/plugins/replication/repl_extop.c -@@ -1412,6 +1412,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) - data->rid = rid; - data->repl_root = slapi_ch_strdup(repl_root); - data->certify = slapi_ch_strdup(certify_all); -+ data->original_task = PR_FALSE; - /* - * Set the aborted rid and stop the cleaning - */ -@@ -1555,6 +1556,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) - data->payload = slapi_ch_bvdup(extop_payload); - data->force = slapi_ch_strdup(force); - data->repl_root = slapi_ch_strdup(repl_root); -+ data->original_task = PR_FALSE; - - thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext, - (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, --- -2.13.6 - diff --git a/SOURCES/0054-Ticket-49184-adjust-logging-level-in-MO-plugin.patch b/SOURCES/0054-Ticket-49184-adjust-logging-level-in-MO-plugin.patch new file mode 100644 index 0000000..7e34e4b --- /dev/null +++ b/SOURCES/0054-Ticket-49184-adjust-logging-level-in-MO-plugin.patch @@ -0,0 +1,30 @@ +From db98cb29158741cc960f1e1a2df3d4214f5bd36e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0054-Ticket-49532-coverity-issues-fix-compiler-warnings-c.patch b/SOURCES/0054-Ticket-49532-coverity-issues-fix-compiler-warnings-c.patch deleted file mode 100644 index 278a45e..0000000 --- a/SOURCES/0054-Ticket-49532-coverity-issues-fix-compiler-warnings-c.patch +++ /dev/null @@ -1,75 +0,0 @@ -From cfa194289ee0c9d26d5775f0b67cf9b481bf357f Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 12 Jan 2018 10:37:18 -0500 -Subject: [PATCH] Ticket 49532 - coverity issues - fix compiler warnings & - clang issues - -Description: Fixed all the warnings - -https://pagure.io/389-ds-base/issue/49532 - -Reviewed by: tbordaz(Thanks!) - -(cherry picked from commit 05907ae05c8a88a64b86747879c002d55d356673) ---- - ldap/servers/slapd/back-ldbm/idl_set.c | 4 ++-- - ldap/servers/slapd/control.c | 2 +- - src/nunc-stans/ns/ns_thrpool.c | 7 ++++++- - 3 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/idl_set.c b/ldap/servers/slapd/back-ldbm/idl_set.c -index b68e7ab76..f9a900f1f 100644 ---- a/ldap/servers/slapd/back-ldbm/idl_set.c -+++ b/ldap/servers/slapd/back-ldbm/idl_set.c -@@ -270,7 +270,7 @@ idl_set_union(IDListSet *idl_set, backend *be) - * Allocate a new set based on the size of our sets. - */ - IDList *result_list = idl_alloc(idl_set->total_size); -- IDList *idl = idl_set->head; -+ IDList *idl = NULL; - IDList *idl_del = NULL; - IDList *prev_idl = NULL; - NIDS last_min = 0; -@@ -398,7 +398,7 @@ idl_set_intersect(IDListSet *idl_set, backend *be) - * we don't care if we have allids here, because we'll ignore it anyway. - */ - result_list = idl_alloc(idl_set->minimum->b_nids); -- IDList *idl = idl_set->head; -+ IDList *idl = NULL; - - /* The previous value we inserted. */ - NIDS last_min = 0; -diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c -index 91d8abb95..366ec7897 100644 ---- a/ldap/servers/slapd/control.c -+++ b/ldap/servers/slapd/control.c -@@ -337,7 +337,7 @@ get_ldapmessage_controls_ext( - slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &ctrl_not_found); - slapi_pblock_set(pb, SLAPI_PWPOLICY, &ctrl_not_found); - slapi_log_err(SLAPI_LOG_CONNS, "get_ldapmessage_controls_ext", "Warning: conn=%" PRIu64 " op=%d contains an empty list of controls\n", -- pb_conn->c_connid, pb_op->o_opid); -+ pb_conn ? pb_conn->c_connid : -1, pb_op ? pb_op->o_opid : -1); - } else { - /* len, ber_len_t is uint, not int, cannot be != -1, may be better to remove this check. */ - if ((tag != LBER_END_OF_SEQORSET) && (len != -1)) { -diff --git a/src/nunc-stans/ns/ns_thrpool.c b/src/nunc-stans/ns/ns_thrpool.c -index 1d8bb03f1..d95b0c38b 100644 ---- a/src/nunc-stans/ns/ns_thrpool.c -+++ b/src/nunc-stans/ns/ns_thrpool.c -@@ -1587,7 +1587,12 @@ ns_thrpool_shutdown(struct ns_thrpool_t *tp) - */ - for (size_t i = 0; i < tp->thread_count; i++) { - ns_result_t result = ns_add_shutdown_job(tp); -- PR_ASSERT(result == NS_SUCCESS); -+ if (result != NS_SUCCESS) { -+#ifdef DEBUG -+ ns_log(LOG_DEBUG, "ns_thrpool_shutdown - Failed to add shutdown job: error (%d)\n", result); -+#endif -+ PR_ASSERT(0); -+ } - } - /* Make sure all threads are woken up to their shutdown jobs. */ - pthread_mutex_lock(&(tp->work_q_lock)); --- -2.13.6 - diff --git a/SOURCES/0055-Ticket-49241-add-symblic-link-location-to-db2bak.pl-.patch b/SOURCES/0055-Ticket-49241-add-symblic-link-location-to-db2bak.pl-.patch new file mode 100644 index 0000000..f5db74e --- /dev/null +++ b/SOURCES/0055-Ticket-49241-add-symblic-link-location-to-db2bak.pl-.patch @@ -0,0 +1,38 @@ +From 6935bd0821395051c0483b0ee393d2d4567f6f0c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0055-Ticket-49523-memberof-schema-violation-error-message.patch b/SOURCES/0055-Ticket-49523-memberof-schema-violation-error-message.patch deleted file mode 100644 index d55ffac..0000000 --- a/SOURCES/0055-Ticket-49523-memberof-schema-violation-error-message.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 60198729ba59f673aae2ae1db1d9668b674ad429 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Fri, 5 Jan 2018 15:31:44 +0100 -Subject: [PATCH] Ticket 49523 - memberof: schema violation error message is - confusing as memberof will likely repair target entry - -Bug Description: - When memberof is enabled it adds 'memberof' attribute to members entries. - If a member entry has not the appropriate objectclass to support 'memberof' attribute an ERR is logged. - - ERR - oc_check_allowed_sv - Entry "cn=user_1,ou=People,dc=example,dc=com" -- attribute "memberOf" not allowed - - This is confusing because memberof will catch this violation and may try to repair it. - So although this message is alarming, the target entry may finally have the 'memberof' attribute. - - This is especially confusing since https://pagure.io/389-ds-base/issue/48985 where the repair operation - is done by default (if schema is violated) - - We can not (and should not) eliminate the schema violation message. - But memberof should log a additional warning (beside the schema violation msg) stating it repaired the violation. - -Fix Description: - - Add a warning message upon repair operation - ERR - oc_check_allowed_sv - Entry "" -- attribute "memberOf" not allowed - WARN - memberof-plugin - Entry - schema violation caught - repair operation succeeded - -https://pagure.io/389-ds-base/issue/49523 - -Reviewed by: Mark Reynolds - -Platforms tested: F26 - -Flag Day: no - -Doc impact: no ---- - dirsrvtests/tests/tickets/ticket49523_test.py | 154 ++++++++++++++++++++++++++ - ldap/servers/plugins/memberof/memberof.c | 8 +- - 2 files changed, 161 insertions(+), 1 deletion(-) - create mode 100644 dirsrvtests/tests/tickets/ticket49523_test.py - -diff --git a/dirsrvtests/tests/tickets/ticket49523_test.py b/dirsrvtests/tests/tickets/ticket49523_test.py -new file mode 100644 -index 000000000..c3296ef07 ---- /dev/null -+++ b/dirsrvtests/tests/tickets/ticket49523_test.py -@@ -0,0 +1,154 @@ -+import logging -+import pytest -+import os -+import ldap -+import time -+import re -+from lib389.plugins import MemberOfPlugin -+from lib389._constants import * -+from lib389.topologies import topology_st as topo -+from lib389 import Entry -+ -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+if DEBUGGING: -+ logging.getLogger(__name__).setLevel(logging.DEBUG) -+else: -+ logging.getLogger(__name__).setLevel(logging.INFO) -+log = logging.getLogger(__name__) -+ -+ -+USER_CN='user_' -+GROUP_CN='group_' -+def _user_get_dn(no): -+ cn = '%s%d' % (USER_CN, no) -+ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX) -+ return (cn, dn) -+ -+def add_user(server, no, desc='dummy', sleep=True): -+ (cn, dn) = _user_get_dn(no) -+ log.fatal('Adding user (%s): ' % dn) -+ server.add_s(Entry((dn, {'objectclass': ['top', 'person'], -+ 'cn': [cn], -+ 'description': [desc], -+ 'sn': [cn], -+ 'description': ['add on that host']}))) -+ if sleep: -+ time.sleep(2) -+ -+def add_group(server, nr, sleep=True): -+ cn = '%s%d' % (GROUP_CN, nr) -+ dn = 'cn=%s,ou=groups,%s' % (cn, SUFFIX) -+ server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'], -+ 'description': 'group %d' % nr}))) -+ if sleep: -+ time.sleep(2) -+ -+def update_member(server, member_dn, group_dn, op, sleep=True): -+ mod = [(op, 'member', member_dn)] -+ server.modify_s(group_dn, mod) -+ if sleep: -+ time.sleep(2) -+ -+def _find_memberof(server, member_dn, group_dn, find_result=True): -+ ent = server.getEntry(member_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof']) -+ found = False -+ if ent.hasAttr('memberof'): -+ -+ for val in ent.getValues('memberof'): -+ server.log.info("!!!!!!! %s: memberof->%s" % (member_dn, val)) -+ server.log.info("!!!!!!! %s" % (val)) -+ server.log.info("!!!!!!! %s" % (group_dn)) -+ if val.lower() == group_dn.lower(): -+ found = True -+ break -+ -+ if find_result: -+ assert (found) -+ else: -+ assert (not found) -+ -+def pattern_accesslog(server, log_pattern): -+ file_obj = open(server.accesslog, "r") -+ -+ found = False -+ # Use a while true iteration because 'for line in file: hit a -+ while True: -+ line = file_obj.readline() -+ found = log_pattern.search(line) -+ if ((line == '') or (found)): -+ break -+ -+ return found -+ -+def pattern_errorlog(server, log_pattern): -+ file_obj = open(server.errlog, "r") -+ -+ found = None -+ # Use a while true iteration because 'for line in file: hit a -+ while True: -+ line = file_obj.readline() -+ found = log_pattern.search(line) -+ server.log.fatal("%s --> %s" % (line, found)) -+ if ((line == '') or (found)): -+ break -+ -+ return found -+ -+def test_ticket49523(topo): -+ """Specify a test case purpose or name here -+ -+ :id: e2af0aaa-447e-4e85-a5ce-57ae66260d0b -+ :setup: Fill in set up configuration here -+ :steps: -+ 1. Fill in test case steps here -+ 2. And indent them like this (RST format requirement) -+ :expectedresults: -+ 1. Fill in the result that is expected -+ 2. For each test step -+ """ -+ -+ # If you need any test suite initialization, -+ # please, write additional fixture for that (including finalizer). -+ # Topology for suites are predefined in lib389/topologies.py. -+ -+ # If you need host, port or any other data about instance, -+ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid) -+ inst = topo.standalone -+ memberof = MemberOfPlugin(inst) -+ memberof.enable() -+ memberof.set_autoaddoc('nsMemberOf') -+ inst.restart() -+ -+ # Step 2 -+ for i in range(10): -+ add_user(inst, i, desc='add user') -+ -+ add_group(inst, 1) -+ -+ group_parent_dn = 'ou=groups,%s' % (SUFFIX) -+ group_rdn = 'cn=%s%d' % (GROUP_CN, 1) -+ group_dn = '%s,%s' % (group_rdn, group_parent_dn) -+ (member_cn, member_dn) = _user_get_dn(1) -+ update_member(inst, member_dn, group_dn, ldap.MOD_ADD, sleep=False) -+ -+ _find_memberof(inst, member_dn, group_dn, find_result=True) -+ -+ pattern = ".*oc_check_allowed_sv - Entry.*cn=%s.* -- attribute.*not allowed.*" % member_cn -+ log.fatal("pattern = %s" % pattern) -+ regex = re.compile(pattern) -+ assert pattern_errorlog(inst, regex) -+ -+ regex = re.compile(".*schema violation caught - repair operation.*") -+ assert pattern_errorlog(inst, regex) -+ -+ if DEBUGGING: -+ # Add debugging steps(if any)... -+ pass -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main("-s %s" % CURRENT_FILE) -+ -diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c -index 44b52edbb..fcfa7817d 100644 ---- a/ldap/servers/plugins/memberof/memberof.c -+++ b/ldap/servers/plugins/memberof/memberof.c -@@ -3236,8 +3236,14 @@ memberof_add_memberof_attr(LDAPMod **mods, const char *dn, char *add_oc) - */ - break; - } -- if (memberof_add_objectclass(add_oc, dn)) { -+ rc = memberof_add_objectclass(add_oc, dn); -+ slapi_log_err(SLAPI_LOG_WARNING, MEMBEROF_PLUGIN_SUBSYSTEM, -+ "Entry %s - schema violation caught - repair operation %s\n", -+ dn ? dn : "unknown", -+ rc ? "failed" : "succeeded"); -+ if (rc) { - /* Failed to add objectclass */ -+ rc = LDAP_OBJECT_CLASS_VIOLATION; - break; - } - added_oc = 1; --- -2.13.6 - diff --git a/SOURCES/0056-Ticket-49313-Change-the-retrochangelog-default-cache.patch b/SOURCES/0056-Ticket-49313-Change-the-retrochangelog-default-cache.patch new file mode 100644 index 0000000..c1089ec --- /dev/null +++ b/SOURCES/0056-Ticket-49313-Change-the-retrochangelog-default-cache.patch @@ -0,0 +1,47 @@ +From 0fc3c803c34311eb05c5c7a7e710c8591b592649 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0056-Ticket-49534-Fix-coverity-issues-and-regression.patch b/SOURCES/0056-Ticket-49534-Fix-coverity-issues-and-regression.patch deleted file mode 100644 index a465a4d..0000000 --- a/SOURCES/0056-Ticket-49534-Fix-coverity-issues-and-regression.patch +++ /dev/null @@ -1,1495 +0,0 @@ -From 961a1d68274453a9a0e79acdd4a3d6e3da146722 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 16 Jan 2018 10:14:34 -0500 -Subject: [PATCH] Ticket 49534 - Fix coverity issues and regression - -Description: Fix regression introdcued in the previous coverity patch. - - Also fixed many other coverity issues. - -https://pagure.io/389-ds-base/issue/49534 - -Reviewed by: wibrown, tbordaz, lkrispen(Thanks!) - -(cherry picked from commit 7658232cc427a5c46e94989eec9195f0392ee540) ---- - ldap/servers/plugins/acl/acl.c | 6 ++++ - ldap/servers/plugins/acl/acllas.c | 13 +++++-- - ldap/servers/plugins/automember/automember.c | 6 ++++ - ldap/servers/plugins/cos/cos_cache.c | 16 +++++++-- - ldap/servers/plugins/memberof/memberof_config.c | 8 ++--- - ldap/servers/plugins/replication/cl5_clcache.c | 9 +++-- - .../plugins/replication/repl5_replica_config.c | 3 -- - ldap/servers/plugins/rootdn_access/rootdn_access.c | 7 +++- - ldap/servers/plugins/uiduniq/7bit.c | 18 +++++----- - ldap/servers/plugins/views/views.c | 3 ++ - ldap/servers/slapd/auth.c | 3 +- - ldap/servers/slapd/back-ldbm/dblayer.c | 5 ++- - ldap/servers/slapd/back-ldbm/filterindex.c | 2 +- - ldap/servers/slapd/back-ldbm/import-threads.c | 10 +++--- - ldap/servers/slapd/back-ldbm/index.c | 3 +- - ldap/servers/slapd/back-ldbm/instance.c | 4 +++ - ldap/servers/slapd/back-ldbm/ldbm_add.c | 18 +++++++--- - .../slapd/back-ldbm/ldbm_attrcrypt_config.c | 7 ++-- - .../servers/slapd/back-ldbm/ldbm_instance_config.c | 2 +- - ldap/servers/slapd/back-ldbm/ldbm_search.c | 4 +-- - ldap/servers/slapd/back-ldbm/vlv.c | 2 +- - ldap/servers/slapd/back-ldbm/vlv_srch.c | 2 +- - ldap/servers/slapd/backend.c | 2 +- - ldap/servers/slapd/compare.c | 7 ++-- - ldap/servers/slapd/connection.c | 40 ++++++++++++---------- - ldap/servers/slapd/control.c | 6 ++++ - ldap/servers/slapd/dse.c | 5 +-- - ldap/servers/slapd/eventq.c | 2 +- - ldap/servers/slapd/extendop.c | 10 +++--- - ldap/servers/slapd/filter.c | 12 ++++--- - ldap/servers/slapd/index_subsystem.c | 2 +- - ldap/servers/slapd/main.c | 19 ++++++++-- - ldap/servers/slapd/mapping_tree.c | 2 +- - ldap/servers/slapd/modify.c | 39 ++++++++++----------- - ldap/servers/slapd/opshared.c | 7 ++++ - ldap/servers/slapd/passwd_extop.c | 4 +++ - ldap/servers/slapd/plugin.c | 8 +++-- - ldap/servers/slapd/plugin_internal_op.c | 1 + - ldap/servers/slapd/psearch.c | 6 ++-- - ldap/servers/slapd/pw.c | 3 +- - ldap/servers/slapd/pw_mgmt.c | 30 ++++++++++------ - ldap/servers/slapd/result.c | 2 +- - ldap/servers/slapd/saslbind.c | 5 +++ - ldap/servers/slapd/task.c | 5 +-- - ldap/servers/slapd/util.c | 12 ++++--- - ldap/servers/slapd/valueset.c | 10 ++++-- - ldap/servers/slapd/vattr.c | 20 ++++++++--- - ldap/servers/snmp/main.c | 19 ++++++---- - 48 files changed, 276 insertions(+), 153 deletions(-) - -diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c -index f10c9f6b5..bc154c78f 100644 ---- a/ldap/servers/plugins/acl/acl.c -+++ b/ldap/servers/plugins/acl/acl.c -@@ -437,6 +437,12 @@ acl_access_allowed( - * pointers to them--we must always start afresh (see psearch.c). - */ - slapi_pblock_get(pb, SLAPI_OPERATION, &op); -+ if (op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, -+ "acl_access_allowed - NULL op\n"); -+ ret_val = LDAP_OPERATIONS_ERROR; -+ goto cleanup_and_ret; -+ } - if (operation_is_flag_set(op, OP_FLAG_PS) || - (aclpb->aclpb_curr_entry_sdn == NULL) || - (slapi_sdn_compare(aclpb->aclpb_curr_entry_sdn, e_sdn) != 0) || -diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c -index b9bea205c..3950fd405 100644 ---- a/ldap/servers/plugins/acl/acllas.c -+++ b/ldap/servers/plugins/acl/acllas.c -@@ -4260,7 +4260,7 @@ acllas_replace_attr_macro(char *rule, lasInfo *lasinfo) - /* - * working_rule is the first member of working_list. - * str points to the next $attr.attrName in working_rule. -- * each member of working_list needs to have each occurence of -+ * each member of working_list needs to have each occurrence of - * $attr.atrName replaced with the value of attrName in e. - * If attrName is multi valued then this generates another - * list which replaces the old one. -@@ -4273,8 +4273,7 @@ acllas_replace_attr_macro(char *rule, lasInfo *lasinfo) - str = strstr(macro_str, "."); - if (!str) { - slapi_log_err(SLAPI_LOG_ERR, plugin_name, -- "acllas_replace_attr_macro - Invalid macro \"%s\".", -- macro_str); -+ "acllas_replace_attr_macro - Invalid macro \"%s\".", macro_str); - slapi_ch_free_string(¯o_str); - charray_free(working_list); - return NULL; -@@ -4282,10 +4281,18 @@ acllas_replace_attr_macro(char *rule, lasInfo *lasinfo) - - str++; /* skip the . */ - l = acl_strstr(&str[0], ")"); -+ if (l == -1){ -+ slapi_log_err(SLAPI_LOG_ERR, plugin_name, -+ "acllas_replace_attr_macro - Invalid macro str \"%s\".", str); -+ slapi_ch_free_string(¯o_str); -+ charray_free(working_list); -+ return NULL; -+ } - macro_attr_name = slapi_ch_malloc(l + 1); - strncpy(macro_attr_name, &str[0], l); - macro_attr_name[l] = '\0'; - -+ - slapi_entry_attr_find(e, macro_attr_name, &attr); - if (NULL == attr) { - -diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c -index 4c008e1f2..cbd25915a 100644 ---- a/ldap/servers/plugins/automember/automember.c -+++ b/ldap/servers/plugins/automember/automember.c -@@ -1047,6 +1047,7 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - /* Order rules by target group DN */ - if (slapi_sdn_compare(rule->target_group_dn, curr_rule->target_group_dn) < 0) { - PR_INSERT_BEFORE(&(rule->list), list); -+ rule = NULL; - break; - } - -@@ -1055,9 +1056,11 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - /* If we hit the end of the list, add to the tail. */ - if ((PRCList *)config->inclusive_rules == list) { - PR_INSERT_BEFORE(&(rule->list), list); -+ rule = NULL; - break; - } - } -+ automember_free_regex_rule(rule); - } else { - /* Add to head of list */ - PR_INSERT_LINK(&(rule->list), (PRCList *)config->inclusive_rules); -@@ -1101,6 +1104,7 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - /* Order rules by target group DN */ - if (slapi_sdn_compare(rule->target_group_dn, curr_rule->target_group_dn) < 0) { - PR_INSERT_BEFORE(&(rule->list), list); -+ rule = NULL; - break; - } - -@@ -1109,6 +1113,7 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - /* If we hit the end of the list, add to the tail. */ - if ((PRCList *)config->exclusive_rules == list) { - PR_INSERT_BEFORE(&(rule->list), list); -+ rule = NULL; - break; - } - } -@@ -1116,6 +1121,7 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - /* Add to head of list */ - PR_INSERT_LINK(&(rule->list), (PRCList *)config->exclusive_rules); - } -+ automember_free_regex_rule(rule); - } else { - slapi_log_err(SLAPI_LOG_ERR, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "automember_parse_regex_entry - Skipping invalid exclusive " -diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c -index 3b3c05783..5e0cf1725 100644 ---- a/ldap/servers/plugins/cos/cos_cache.c -+++ b/ldap/servers/plugins/cos/cos_cache.c -@@ -874,7 +874,7 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data) - - if (pCosAttribute && (!pCosTargetTree || !pCosTemplateDn)) { - /* get the parent of the definition */ -- char *orig = slapi_dn_parent(pDn->val); -+ char *orig = pDn ? slapi_dn_parent(pDn->val) : NULL; - char *parent = NULL; - if (orig) { - parent = slapi_create_dn_string("%s", orig); -@@ -900,7 +900,7 @@ cos_dn_defs_cb(Slapi_Entry *e, void *callback_data) - slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, - "cos_dn_defs_cb - " - "Failed to get parent dn of cos definition %s.\n", -- pDn->val); -+ pDn ? pDn->val : ""); - if (!pCosTemplateDn) { - if (!pCosTargetTree) { - slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTargetTree and cosTemplateDn are not set.\n"); -@@ -1843,6 +1843,13 @@ cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAttrValue *ob - - slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_add_tmpl\n"); - -+ if (dn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, -+ "cos_cache_add_tmpl - param cosAttrValue dn is NULL\n"); -+ ret = -1; -+ goto done; -+ } -+ - /* create the attribute */ - theTemp = (cosTemplates *)slapi_ch_malloc(sizeof(cosTemplates)); - if (theTemp) { -@@ -1851,7 +1858,9 @@ cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAttrValue *ob - int index = 0; - int template_default = 0; - char *ptr = NULL; -- char *normed = slapi_create_dn_string("%s", dn->val); -+ char *normed = NULL; -+ -+ normed = slapi_create_dn_string("%s", dn->val); - if (normed) { - slapi_ch_free_string(&dn->val); - dn->val = normed; -@@ -1964,6 +1973,7 @@ cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAttrValue *ob - ret = -1; - } - -+done: - slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_add_tmpl\n"); - return ret; - } -diff --git a/ldap/servers/plugins/memberof/memberof_config.c b/ldap/servers/plugins/memberof/memberof_config.c -index 3f22d95d6..8a27f5250 100644 ---- a/ldap/servers/plugins/memberof/memberof_config.c -+++ b/ldap/servers/plugins/memberof/memberof_config.c -@@ -550,7 +550,7 @@ memberof_apply_config(Slapi_PBlock *pb __attribute__((unused)), - } - - /* Build the new list */ -- for (i = 0; theConfig.groupattrs[i]; i++) { -+ for (i = 0; theConfig.groupattrs && theConfig.groupattrs[i]; i++) { - theConfig.group_slapiattrs[i] = slapi_attr_new(); - slapi_attr_init(theConfig.group_slapiattrs[i], theConfig.groupattrs[i]); - } -@@ -572,7 +572,7 @@ memberof_apply_config(Slapi_PBlock *pb __attribute__((unused)), - bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|"); - - /* Add filter section for each groupattr. */ -- for (i = 0; theConfig.groupattrs[i]; i++) { -+ for (i = 0; theConfig.groupattrs && theConfig.groupattrs[i]; i++) { - bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out, "(%s=*)", theConfig.groupattrs[i]); - } - -@@ -721,7 +721,7 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) - } - - /* Count how many values we have in the source list. */ -- for (j = 0; src->group_slapiattrs[j]; j++) { -+ for (j = 0; src->group_slapiattrs && src->group_slapiattrs[j]; j++) { - /* Do nothing. */ - } - -@@ -731,7 +731,7 @@ memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src) - } - - /* Copy the attributes. */ -- for (i = 0; src->group_slapiattrs[i]; i++) { -+ for (i = 0; src->group_slapiattrs && src->group_slapiattrs[i]; i++) { - dest->group_slapiattrs[i] = slapi_attr_dup(src->group_slapiattrs[i]); - } - -diff --git a/ldap/servers/plugins/replication/cl5_clcache.c b/ldap/servers/plugins/replication/cl5_clcache.c -index 40985b9a7..a8477a83a 100644 ---- a/ldap/servers/plugins/replication/cl5_clcache.c -+++ b/ldap/servers/plugins/replication/cl5_clcache.c -@@ -676,7 +676,7 @@ clcache_initial_anchorcsn(CLC_Buffer *buf, int *flag) - buf->buf_state = CLC_STATE_DONE; - } else { - csn_init_by_csn(buf->buf_current_csn, anchorcsn); -- csn_as_string(buf->buf_current_csn, 0, (char *)buf->buf_key.data); -+ buf->buf_key.data = csn_as_string(buf->buf_current_csn, 0, (char *)buf->buf_key.data); - slapi_log_err(SLAPI_LOG_REPL, "clcache_initial_anchorcsn", - "anchor is now: %s\n", (char *)buf->buf_key.data); - } -@@ -746,10 +746,9 @@ clcache_adjust_anchorcsn(CLC_Buffer *buf, int *flag) - buf->buf_state = CLC_STATE_DONE; - } else { - csn_init_by_csn(buf->buf_current_csn, anchorcsn); -- csn_as_string(buf->buf_current_csn, 0, (char *)buf->buf_key.data); -- slapi_log_err(SLAPI_LOG_REPL, buf->buf_agmt_name, "clcache_adjust_anchorcsn - " -- "anchor is now: %s\n", -- (char *)buf->buf_key.data); -+ buf->buf_key.data = csn_as_string(buf->buf_current_csn, 0, (char *)buf->buf_key.data); -+ slapi_log_err(SLAPI_LOG_REPL, buf->buf_agmt_name, -+ "clcache_adjust_anchorcsn - anchor is now: %s\n", (char *)buf->buf_key.data); - } - - return buf->buf_state; -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index 95b933bb8..bda333362 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -2527,9 +2527,6 @@ add_cleaned_rid(cleanruv_data *cleanruv_data, char *maxcsn) - Replica *r; - char *forcing; - -- if (data == NULL) { -- return; -- } - rid = cleanruv_data->rid; - r = cleanruv_data->replica; - forcing = cleanruv_data->force; -diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c -index b4db1202a..1cb999792 100644 ---- a/ldap/servers/plugins/rootdn_access/rootdn_access.c -+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c -@@ -459,7 +459,7 @@ rootdn_check_access(Slapi_PBlock *pb) - PRNetAddr *client_addr = NULL; - PRHostEnt *host_entry = NULL; - time_t curr_time; -- struct tm *timeinfo; -+ struct tm *timeinfo = NULL; - char *dnsName = NULL; - int isRoot = 0; - int rc = SLAPI_PLUGIN_SUCCESS; -@@ -478,6 +478,11 @@ rootdn_check_access(Slapi_PBlock *pb) - if (open_time || daysAllowed) { - curr_time = slapi_current_utc_time(); - timeinfo = localtime(&curr_time); -+ if (timeinfo == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, -+ "rootdn_check_access - Failed to get localtime\n"); -+ return -1; -+ } - } - /* - * First check TOD restrictions, continue through if we are in the open "window" -diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c -index b23e652cf..60fcbab93 100644 ---- a/ldap/servers/plugins/uiduniq/7bit.c -+++ b/ldap/servers/plugins/uiduniq/7bit.c -@@ -715,18 +715,18 @@ preop_modrdn(Slapi_PBlock *pb) - int - NS7bitAttr_Init(Slapi_PBlock *pb) - { -- int err = 0; -+ int32_t err = 0; - Slapi_Entry *plugin_entry = NULL; - char *plugin_type = NULL; -- int preadd = SLAPI_PLUGIN_PRE_ADD_FN; -- int premod = SLAPI_PLUGIN_PRE_MODIFY_FN; -- int premdn = SLAPI_PLUGIN_PRE_MODRDN_FN; -+ int32_t preadd = SLAPI_PLUGIN_PRE_ADD_FN; -+ int32_t premod = SLAPI_PLUGIN_PRE_MODIFY_FN; -+ int32_t premdn = SLAPI_PLUGIN_PRE_MODRDN_FN; - - BEGIN -- int attr_count = 0; -- int argc; -- char **argv; -- int valid_suffix = 0; -+ int32_t attr_count = 0; -+ int32_t argc = 0; -+ char **argv = NULL; -+ int32_t valid_suffix = 0; - - /* Declare plugin version */ - err = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, -@@ -752,7 +752,7 @@ NS7bitAttr_Init(Slapi_PBlock *pb) - break; - - err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv); -- if (err) -+ if (err || argv == NULL) - break; - - for (attr_count = 0; argv && argv[attr_count]; attr_count++) { -diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c -index 6ba3e290d..6f784f599 100644 ---- a/ldap/servers/plugins/views/views.c -+++ b/ldap/servers/plugins/views/views.c -@@ -558,6 +558,9 @@ views_cache_index(void) - /* copy over the views */ - for (i = 0; i < theCache.view_count; i++) { - theCache.ppViewIndex[i] = theView; -+ if (theView == NULL){ -+ break; -+ } - theView = theView->list.pNext; - } - -diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c -index b8e171b27..a2050b990 100644 ---- a/ldap/servers/slapd/auth.c -+++ b/ldap/servers/slapd/auth.c -@@ -463,7 +463,8 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) - slapi_log_access(LDAP_DEBUG_STATS, - "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", - conn->c_connid, -- sslversion, keySize, cipher ? cipher : "NULL", -+ sslversion, keySize, -+ cipher ? cipher : "NULL", - subject ? escape_string(subject, sbuf) : "NULL", - issuer ? escape_string(issuer, ibuf) : "NULL"); - if (issuer) -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index 9e557a24a..5d870e364 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -3007,7 +3007,7 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in - struct dblayer_private_env *pEnv = NULL; - ldbm_instance *inst = NULL; - dblayer_handle *handle = NULL; -- char dbName[MAXPATHLEN]; -+ char dbName[MAXPATHLEN] = {0}; - char *dbNamep; - char *p; - int dbbasenamelen, dbnamelen; -@@ -3098,8 +3098,7 @@ dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, PRBool use_lock, in - dbNamep = (char *)slapi_ch_realloc(dbNamep, dbnamelen); - } - p = dbNamep + dbbasenamelen; -- sprintf(p, "%c%s%s", -- get_sep(dbNamep), a->ai_type, LDBM_FILENAME_SUFFIX); -+ sprintf(p, "%c%s%s", get_sep(dbNamep), a->ai_type, LDBM_FILENAME_SUFFIX); - rc = dblayer_db_remove_ex(pEnv, dbNamep, 0, 0); - a->ai_dblayer = NULL; - if (dbNamep != dbName) -diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c -index fd079077c..e8c3c2008 100644 ---- a/ldap/servers/slapd/back-ldbm/filterindex.c -+++ b/ldap/servers/slapd/back-ldbm/filterindex.c -@@ -563,7 +563,7 @@ range_candidates( - - /* Check if it is for bulk import. */ - slapi_pblock_get(pb, SLAPI_OPERATION, &op); -- if (entryrdn_get_switch() && operation_is_flag_set(op, OP_FLAG_INTERNAL) && -+ if (entryrdn_get_switch() && op && operation_is_flag_set(op, OP_FLAG_INTERNAL) && - operation_is_flag_set(op, OP_FLAG_BULK_IMPORT)) { - /* parentid is treated specially that is needed for the bulk import. (See #48755) */ - operator= SLAPI_OP_RANGE_NO_IDL_SORT | SLAPI_OP_RANGE_NO_ALLIDS; -diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c -index b8cd9aaa0..0419865c9 100644 ---- a/ldap/servers/slapd/back-ldbm/import-threads.c -+++ b/ldap/servers/slapd/back-ldbm/import-threads.c -@@ -1664,8 +1664,7 @@ upgradedn_producer(void *param) - slapi_ch_free_string(&rdn); - } - } else { -- e = -- slapi_str2entry(data.data, SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT); -+ e = slapi_str2entry(data.data, SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT); - rdn = slapi_ch_strdup(slapi_entry_get_rdn_const(e)); - if (NULL == rdn) { - Slapi_RDN srdn; -@@ -1683,6 +1682,7 @@ upgradedn_producer(void *param) - slapi_log_err(SLAPI_LOG_WARNING, "upgradedn_producer", - "%s: Skipping badly formatted entry (id %lu)\n", - inst->inst_name, (u_long)temp_id); -+ slapi_ch_free_string(&rdn); - continue; - } - -@@ -2183,6 +2183,7 @@ done: - free_IDarray(&dn_norm_sp_conflicts); - slapi_ch_free_string(&ecopy); - slapi_ch_free(&(data.data)); -+ slapi_ch_free_string(&rdn); - if (job->upgradefd) { - fclose(job->upgradefd); - } -@@ -3783,7 +3784,7 @@ out: - slapi_ch_free_string(&search_scope); - - -- if (fd > 0) { -+ if (fd >= 0) { - close(fd); - } - -@@ -3949,8 +3950,7 @@ import_get_and_add_parent_rdns(ImportWorkerInfo *info, - rc = slapi_rdn_add_srdn_to_all_rdns(srdn, &mysrdn); - if (rc) { - slapi_log_err(SLAPI_LOG_ERR, "import_get_and_add_parent_rdns", -- "Failed to merge Slapi_RDN %s to RDN\n", -- slapi_sdn_get_dn(bdn->dn_sdn)); -+ "Failed to merge Slapi_RDN to RDN\n"); - } - bail: - slapi_ch_free(&data.data); -diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c -index 587f4d991..7e1cdd0db 100644 ---- a/ldap/servers/slapd/back-ldbm/index.c -+++ b/ldap/servers/slapd/back-ldbm/index.c -@@ -749,7 +749,7 @@ index_add_mods( - mods[i]->mod_type, - &curr_attr); - if (curr_attr) { -- for (j = 0; mods_valueArray[j] != NULL; j++) { -+ for (j = 0; mods_valueArray && mods_valueArray[j] != NULL; j++) { - if (!slapi_valueset_find(curr_attr, all_vals, mods_valueArray[j])) { - /* - * If the mod del value is not found in all_vals -@@ -1054,6 +1054,7 @@ index_read_ext_allids( - for (retry_count = 0; retry_count < IDL_FETCH_RETRY_COUNT; retry_count++) { - *err = NEW_IDL_DEFAULT; - PRIntervalTime interval; -+ idl_free(&idl); - idl = idl_fetch_ext(be, db, &key, db_txn, ai, err, allidslimit); - if (*err == DB_LOCK_DEADLOCK) { - ldbm_nasty("index_read_ext_allids", "index read retrying transaction", 1045, *err); -diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c -index d4715ab9c..7f9f423a5 100644 ---- a/ldap/servers/slapd/back-ldbm/instance.c -+++ b/ldap/servers/slapd/back-ldbm/instance.c -@@ -352,6 +352,10 @@ ldbm_instance_find_by_name(struct ldbminfo *li, char *name) - Object *inst_obj; - ldbm_instance *inst; - -+ if (name == NULL) { -+ return NULL; -+ } -+ - inst_obj = objset_first_obj(li->li_instance_set); - while (inst_obj != NULL) { - inst = (ldbm_instance *)object_get_data(inst_obj); -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c -index f29945a7e..c93d44a65 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c -@@ -60,7 +60,7 @@ ldbm_back_add(Slapi_PBlock *pb) - ID pid; - int isroot; - char *errbuf = NULL; -- back_txn txn; -+ back_txn txn = {0}; - back_txnid parent_txn; - int retval = -1; - char *msg; -@@ -96,6 +96,7 @@ ldbm_back_add(Slapi_PBlock *pb) - PRUint64 conn_id; - int op_id; - int result_sent = 0; -+ - if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) { - conn_id = 0; /* connection is NULL */ - } -@@ -109,6 +110,11 @@ ldbm_back_add(Slapi_PBlock *pb) - slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation); - slapi_pblock_get(pb, SLAPI_BACKEND, &be); - -+ if (operation == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add", "NULL operation\n"); -+ return LDAP_OPERATIONS_ERROR; -+ } -+ - is_resurect_operation = operation_is_flag_set(operation, OP_FLAG_RESURECT_ENTRY); - is_tombstone_operation = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY); - is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP); -@@ -126,6 +132,11 @@ ldbm_back_add(Slapi_PBlock *pb) - goto error_return; - } - -+ if (e == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add", "entry is NULL.\n"); -+ goto error_return; -+ } -+ - /* sdn & parentsdn need to be initialized before "goto *_return" */ - slapi_sdn_init(&parentsdn); - -@@ -169,9 +180,8 @@ ldbm_back_add(Slapi_PBlock *pb) - * before we make our last abandon check to avoid race conditions in - * the code that processes abandon operations. - */ -- if (operation) { -- operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE; -- } -+ operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE; -+ - if (slapi_op_abandoned(pb)) { - ldap_result_code = -1; /* needs to distinguish from "success" */ - goto error_return; -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c -index e792c26cf..9ecb09903 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c -@@ -124,8 +124,8 @@ ldbm_instance_attrcrypt_config_add_callback(Slapi_PBlock *pb __attribute__((unus - { - ldbm_instance *inst = (ldbm_instance *)arg; - char *attribute_name = NULL; -- int cipher = 0; -- int ret = 0; -+ int32_t cipher = 0; -+ int32_t ret = SLAPI_DSE_CALLBACK_OK; - - returntext[0] = '\0'; - -@@ -146,7 +146,6 @@ ldbm_instance_attrcrypt_config_add_callback(Slapi_PBlock *pb __attribute__((unus - *returncode = LDAP_UNWILLING_TO_PERFORM; - ret = SLAPI_DSE_CALLBACK_ERROR; - } else { -- - ainfo_get(inst->inst_be, attribute_name, &ai); - /* If we couldn't find a non-default attrinfo, then that means - * that no indexing or encryption has yet been defined for this attribute -@@ -172,9 +171,7 @@ ldbm_instance_attrcrypt_config_add_callback(Slapi_PBlock *pb __attribute__((unus - *returncode = LDAP_UNWILLING_TO_PERFORM; - ret = SLAPI_DSE_CALLBACK_ERROR; - } -- ret = SLAPI_DSE_CALLBACK_OK; - } -- - } else { - ret = SLAPI_DSE_CALLBACK_ERROR; - } -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -index c2e49d5ab..eb2603897 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c -@@ -1307,7 +1307,7 @@ ldbm_instance_delete_instance_entry_callback(Slapi_PBlock *pb __attribute__((unu - char *returntext, - void *arg) - { -- char *instance_name; -+ char *instance_name = NULL; - struct ldbminfo *li = (struct ldbminfo *)arg; - struct ldbm_instance *inst = NULL; - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c -index 02a21bf92..8f3111813 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_search.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c -@@ -1157,7 +1157,7 @@ subtree_candidates( - slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); - /* Check if it is for bulk import. */ - slapi_pblock_get(pb, SLAPI_OPERATION, &op); -- if (entryrdn_get_switch() && operation_is_flag_set(op, OP_FLAG_INTERNAL) && -+ if (op && entryrdn_get_switch() && operation_is_flag_set(op, OP_FLAG_INTERNAL) && - operation_is_flag_set(op, OP_FLAG_BULK_IMPORT)) { - is_bulk_import = PR_TRUE; - } -@@ -1168,7 +1168,7 @@ subtree_candidates( - * since tombstone entries are not indexed in the ancestorid index. - * Note: they are indexed in the entryrdn index. - */ -- if (candidates != NULL && (idl_length(candidates) > FILTER_TEST_THRESHOLD)) { -+ if (candidates != NULL && (idl_length(candidates) > FILTER_TEST_THRESHOLD) && e) { - IDList *tmp = candidates, *descendants = NULL; - back_txn txn = {NULL}; - -diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c -index 9a1a1c63e..23825c2d5 100644 ---- a/ldap/servers/slapd/back-ldbm/vlv.c -+++ b/ldap/servers/slapd/back-ldbm/vlv.c -@@ -1518,7 +1518,7 @@ vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_sp - { - PRUint32 si = 0; /* The Selected Index */ - PRUint32 low = 0; -- PRUint32 high = candidates->b_nids - 1; -+ PRUint32 high = 0; - PRUint32 current = 0; - ID id = NOID; - int found = 0; -diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c -index e9780b590..c4c0875ad 100644 ---- a/ldap/servers/slapd/back-ldbm/vlv_srch.c -+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c -@@ -168,7 +168,7 @@ vlvSearch_init(struct vlvSearch *p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm - - /* switch context back to the DSE backend */ - slapi_pblock_set(pb, SLAPI_BACKEND, oldbe); -- slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe->be_database); -+ slapi_pblock_set(pb, SLAPI_PLUGIN, oldbe ? oldbe->be_database: NULL); - } - - /* make (&(parentid=idofbase)(|(originalfilter)(objectclass=referral))) */ -diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c -index fb3eb77a3..78c00a5a8 100644 ---- a/ldap/servers/slapd/backend.c -+++ b/ldap/servers/slapd/backend.c -@@ -171,7 +171,7 @@ slapi_be_issuffix(const Slapi_Backend *be, const Slapi_DN *suffix) - struct suffixlist *list; - int r = 0; - /* this backend is no longer valid */ -- if (be->be_state != BE_STATE_DELETED) { -+ if (be && be->be_state != BE_STATE_DELETED) { - int i = 0, count; - - count = slapi_counter_get_value(be->be_suffixcounter); -diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c -index 2626d91d0..88a6c3599 100644 ---- a/ldap/servers/slapd/compare.c -+++ b/ldap/servers/slapd/compare.c -@@ -47,9 +47,11 @@ do_compare(Slapi_PBlock *pb) - - slapi_log_err(SLAPI_LOG_TRACE, "do_compare", "=>\n"); - -+ /* have to init this here so we can "done" it below if we short circuit */ -+ slapi_sdn_init(&sdn); -+ - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- - if (pb_op == NULL || pb_conn == NULL) { - slapi_log_err(SLAPI_LOG_ERR, "do_compare", "NULL param: pb_conn (0x%p) pb_op (0x%p)\n", - pb_conn, pb_op); -@@ -62,9 +64,6 @@ do_compare(Slapi_PBlock *pb) - /* count the compare request */ - slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); - -- /* have to init this here so we can "done" it below if we short circuit */ -- slapi_sdn_init(&sdn); -- - /* - * Parse the compare request. It looks like this: - * -diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c -index fa24ec040..5d2b64ed2 100644 ---- a/ldap/servers/slapd/connection.c -+++ b/ldap/servers/slapd/connection.c -@@ -1526,18 +1526,6 @@ connection_threadmain() - [blackflag 624234] */ - ret = connection_wait_for_new_work(pb, interval); - -- /* -- * Connection wait for new work provides the conn and op for us. -- */ -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- if (pb_conn == NULL) { -- slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", -- "pb_conn is NULL\n"); -- slapi_pblock_destroy(pb); -- g_decr_active_threadcnt(); -- return; -- } -- - switch (ret) { - case CONN_NOWORK: - PR_ASSERT(interval != PR_INTERVAL_NO_TIMEOUT); /* this should never happen with PR_INTERVAL_NO_TIMEOUT */ -@@ -1550,15 +1538,22 @@ connection_threadmain() - return; - case CONN_FOUND_WORK_TO_DO: - /* note - don't need to lock here - connection should only -- be used by this thread - since c_gettingber is set to 1 -- in connection_activity when the conn is added to the -- work queue, setup_pr_read_pds won't add the connection prfd -- to the poll list */ -+ be used by this thread - since c_gettingber is set to 1 -+ in connection_activity when the conn is added to the -+ work queue, setup_pr_read_pds won't add the connection prfd -+ to the poll list */ -+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (pb_conn == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", "pb_conn is NULL\n"); -+ slapi_pblock_destroy(pb); -+ g_decr_active_threadcnt(); -+ return; -+ } - if (pb_conn->c_opscompleted == 0) { - /* -- * We have a new connection, set the anonymous reslimit idletimeout -- * if applicable. -- */ -+ * We have a new connection, set the anonymous reslimit idletimeout -+ * if applicable. -+ */ - char *anon_dn = config_get_anon_limits_dn(); - int idletimeout; - /* If an anonymous limits dn is set, use it to set the limits. */ -@@ -1578,6 +1573,7 @@ connection_threadmain() - slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", - "Could not add/remove IO layers from connection\n"); - } -+ break; - default: - break; - } -@@ -1604,6 +1600,12 @@ connection_threadmain() - /* Once we're here we have a pb */ - slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); - slapi_pblock_get(pb, SLAPI_OPERATION, &op); -+ if (conn == NULL || op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", "NULL param: conn (0x%p) op (0x%p)\n", conn, op); -+ slapi_pblock_destroy(pb); -+ g_decr_active_threadcnt(); -+ return; -+ } - maxthreads = config_get_maxthreadsperconn(); - more_data = 0; - ret = connection_read_operation(conn, op, &tag, &more_data); -diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c -index 366ec7897..4fd8473be 100644 ---- a/ldap/servers/slapd/control.c -+++ b/ldap/servers/slapd/control.c -@@ -304,6 +304,12 @@ get_ldapmessage_controls_ext( - - Operation *pb_op = NULL; - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -+ if (pb_op == NULL) { -+ rc = LDAP_OPERATIONS_ERROR; -+ slapi_log_err(SLAPI_LOG_ERR, "get_ldapmessage_controls_ext", "NULL pb_op\n"); -+ slapi_rwlock_unlock(supported_controls_lock); -+ goto free_and_return; -+ } - - if (supported_controls == NULL || - supported_controls[i] == NULL || -diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c -index 662e91aa7..932912c17 100644 ---- a/ldap/servers/slapd/dse.c -+++ b/ldap/servers/slapd/dse.c -@@ -1727,8 +1727,9 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit point from thi - } - - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -- internal_op = operation_is_flag_set(pb_op, OP_FLAG_INTERNAL); -- -+ if (pb_op){ -+ internal_op = operation_is_flag_set(pb_op, OP_FLAG_INTERNAL); -+ } - /* Find the entry we are about to modify. */ - ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK); - if (ec == NULL) { -diff --git a/ldap/servers/slapd/eventq.c b/ldap/servers/slapd/eventq.c -index 8fccf38a8..a491acd0a 100644 ---- a/ldap/servers/slapd/eventq.c -+++ b/ldap/servers/slapd/eventq.c -@@ -462,7 +462,7 @@ slapi_eq_get_arg(Slapi_Eq_Context ctx) - slapi_eq_context **p; - - PR_ASSERT(eq_initialized); -- if (!eq_stopped) { -+ if (eq && !eq_stopped) { - PR_Lock(eq->eq_lock); - p = &(eq->eq_queue); - while (p && *p != NULL) { -diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c -index 815949be6..98595bcaa 100644 ---- a/ldap/servers/slapd/extendop.c -+++ b/ldap/servers/slapd/extendop.c -@@ -135,10 +135,12 @@ extop_handle_import_start(Slapi_PBlock *pb, char *extoid __attribute__((unused)) - * connection block & mark this connection as belonging to a bulk import - */ - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- PR_EnterMonitor(pb_conn->c_mutex); -- pb_conn->c_flags |= CONN_FLAG_IMPORT; -- pb_conn->c_bi_backend = be; -- PR_ExitMonitor(pb_conn->c_mutex); -+ if (pb_conn) { -+ PR_EnterMonitor(pb_conn->c_mutex); -+ pb_conn->c_flags |= CONN_FLAG_IMPORT; -+ pb_conn->c_bi_backend = be; -+ PR_ExitMonitor(pb_conn->c_mutex); -+ } - - slapi_pblock_set(pb, SLAPI_EXT_OP_RET_OID, EXTOP_BULK_IMPORT_START_OID); - bv.bv_val = NULL; -diff --git a/ldap/servers/slapd/filter.c b/ldap/servers/slapd/filter.c -index ef975e679..2ac3d2cd8 100644 ---- a/ldap/servers/slapd/filter.c -+++ b/ldap/servers/slapd/filter.c -@@ -686,11 +686,13 @@ slapi_filter_dup(Slapi_Filter *f) - outl = &out->f_list; - for (fl = f->f_list; fl != NULL; fl = fl->f_next) { - (*outl) = slapi_filter_dup(fl); -- (*outl)->f_next = 0; -- if (lastout) -- lastout->f_next = *outl; -- lastout = *outl; -- outl = &((*outl)->f_next); -+ if (*outl){ -+ (*outl)->f_next = 0; -+ if (lastout) -+ lastout->f_next = *outl; -+ lastout = *outl; -+ outl = &((*outl)->f_next); -+ } - } - break; - -diff --git a/ldap/servers/slapd/index_subsystem.c b/ldap/servers/slapd/index_subsystem.c -index 47ca90047..97cb7b489 100644 ---- a/ldap/servers/slapd/index_subsystem.c -+++ b/ldap/servers/slapd/index_subsystem.c -@@ -1179,7 +1179,7 @@ index_subsys_assign_decoder(Slapi_Filter *f) - * have the same associated attributes configuration for now - * though they may have different namespaces - */ -- if (index_subsys_index_matches_index(f->assigned_decoder, index)) { -+ if (index_subsys_index_matches_index(f->assigned_decoder, index) && last) { - /* add to end */ - last->list.pNext = index_subsys_index_shallow_dup(index); - last = last->list.pNext; -diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c -index ddaceffea..e1493bb80 100644 ---- a/ldap/servers/slapd/main.c -+++ b/ldap/servers/slapd/main.c -@@ -683,13 +683,26 @@ main(int argc, char **argv) - { - char *s = getenv("DEBUG_SLEEP"); - if ((s != NULL) && isdigit(*s)) { -- int secs = atoi(s); -- printf("slapd pid is %d\n", getpid()); -+ char *endp = NULL; -+ int64_t secs; -+ errno = 0; -+ -+ secs = strtol(s, &endp, 10); -+ if ( endp == s || -+ *endp != '\0' || -+ ((secs == LONG_MIN || secs == LONG_MAX) && errno == ERANGE) || -+ secs < 1 ) -+ { -+ /* Invalid value, default to 30 seconds */ -+ secs = 30; -+ } else if (secs > 3600) { -+ secs = 3600; -+ } -+ printf("slapd pid is %d - sleeping for %ld\n", getpid(), secs); - sleep(secs); - } - } - -- - /* used to set configfile to the default config file name here */ - if ((mcfg.myname = strrchr(argv[0], '/')) == NULL) { - mcfg.myname = slapi_ch_strdup(argv[0]); -diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c -index 8cc531834..472a2f6aa 100644 ---- a/ldap/servers/slapd/mapping_tree.c -+++ b/ldap/servers/slapd/mapping_tree.c -@@ -2629,7 +2629,7 @@ mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb, Slapi_Backend **be, - (target_node->mtn_be_states[*index] == SLAPI_BE_STATE_OFFLINE)) { - slapi_log_err(SLAPI_LOG_TRACE, "mtn_get_be", - "Operation attempted on backend in OFFLINE state : %s\n", -- target_node->mtn_backend_names[*index]); -+ target_node->mtn_backend_names ? target_node->mtn_backend_names[*index] : "Unknown backend"); - result = LDAP_OPERATIONS_ERROR; - *be = defbackend_get_backend(); - } -diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c -index 10d263159..f2f6d1783 100644 ---- a/ldap/servers/slapd/modify.c -+++ b/ldap/servers/slapd/modify.c -@@ -123,7 +123,7 @@ do_modify(Slapi_PBlock *pb) - - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- if (operation == NULL) { -+ if (operation == NULL || pb_conn == NULL) { - send_ldap_result(pb, LDAP_OPERATIONS_ERROR, - NULL, "operation is NULL parameter", 0, NULL); - slapi_log_err(SLAPI_LOG_ERR, "do_modify", -@@ -1156,6 +1156,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - char *proxydn = NULL; - char *proxystr = NULL; - char *errtext = NULL; -+ int32_t needpw = 0; - - slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op); - if (repl_op) { -@@ -1169,24 +1170,23 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); - slapi_pblock_get(pb, SLAPI_PWPOLICY, &pwresponse_req); -- internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ slapi_sdn_init_dn_byref(&sdn, dn); - -- if (pb_conn == NULL || operation == NULL) { -- slapi_log_err(SLAPI_LOG_ERR, "op_shared_allow_pw_change", -- "NULL param error: conn (0x%p) op (0x%p)\n", pb_conn, operation); -+ if (operation == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "op_shared_allow_pw_change", "NULL operation\n"); - rc = -1; - goto done; - } -- -- slapi_sdn_init_dn_byref(&sdn, dn); -- pwpolicy = new_passwdPolicy(pb, (char *)slapi_sdn_get_ndn(&sdn)); -+ if (pb_conn) { -+ needpw = pb_conn->c_needpw; -+ } - - /* get the proxy auth dn if the proxy auth control is present */ - if ((proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext)) != LDAP_SUCCESS) { - if (operation_is_flag_set(operation, OP_FLAG_ACTION_LOG_ACCESS)) { - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"\n", -- pb_conn->c_connid, operation->o_opid, -+ pb_conn ? pb_conn->c_connid: -1, operation->o_opid, - slapi_sdn_get_dn(&sdn)); - } - -@@ -1195,6 +1195,9 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - goto done; - } - -+ pwpolicy = new_passwdPolicy(pb, (char *)slapi_sdn_get_ndn(&sdn)); -+ internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL); -+ - /* internal operation has root permissions for subtrees it is allowed to access */ - if (!internal_op) { - /* slapi_acl_check_mods needs an array of LDAPMods, but -@@ -1225,7 +1228,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); - } - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s\n", -- pb_conn->c_connid, operation->o_opid, -+ pb_conn ? pb_conn->c_connid : -1, operation->o_opid, - slapi_sdn_get_dn(&sdn), proxystr ? proxystr : ""); - } - -@@ -1254,7 +1257,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - - /* Check if password policy allows users to change their passwords.*/ - if (!operation->o_isroot && slapi_sdn_compare(&sdn, &operation->o_sdn) == 0 && -- !pb_conn->c_needpw && !pwpolicy->pw_change) { -+ !needpw && !pwpolicy->pw_change) { - if (pwresponse_req == 1) { - slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDMODNOTALLOWED); - } -@@ -1267,7 +1270,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - } - - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", -- pb_conn->c_connid, operation->o_opid, -+ pb_conn ? pb_conn->c_connid : -1, operation->o_opid, - slapi_sdn_get_dn(&sdn), - proxystr ? proxystr : "", - "user is not allowed to change password"); -@@ -1280,8 +1283,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - - /* check if password is within password minimum age; - error result is sent directly from check_pw_minage */ -- if (pb_conn && !pb_conn->c_needpw && -- check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1) { -+ if (!needpw && check_pw_minage(pb, &sdn, mod->mod_bvalues) == 1) { - if (operation_is_flag_set(operation, OP_FLAG_ACTION_LOG_ACCESS)) { - if (proxydn) { - proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); -@@ -1289,7 +1291,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - - if (!internal_op) { - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", -- pb_conn->c_connid, -+ pb_conn ? pb_conn->c_connid : -1, - operation->o_opid, - slapi_sdn_get_dn(&sdn), - proxystr ? proxystr : "", -@@ -1303,17 +1305,14 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - "within password minimum age"); - } - } -- - rc = -1; - goto done; - } - -- - /* check password syntax; remember the old password; - error sent directly from check_pw_syntax function */ - valuearray_init_bervalarray(mod->mod_bvalues, &values); -- switch (check_pw_syntax_ext(pb, &sdn, values, old_pw, NULL, -- mod->mod_op, smods)) { -+ switch (check_pw_syntax_ext(pb, &sdn, values, old_pw, NULL, mod->mod_op, smods)) { - case 0: /* success */ - rc = 1; - break; -@@ -1326,7 +1325,7 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M - - if (!internal_op) { - slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " op=%d MOD dn=\"%s\"%s, %s\n", -- pb_conn->c_connid, -+ pb_conn ? pb_conn->c_connid : -1, - operation->o_opid, - slapi_sdn_get_dn(&sdn), - proxystr ? proxystr : "", -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 46dcf6fba..50b7ae8f6 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -276,6 +276,13 @@ op_shared_search(Slapi_PBlock *pb, int send_result) - slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &fstr); - slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs); - slapi_pblock_get(pb, SLAPI_OPERATION, &operation); -+ if (operation == NULL) { -+ op_shared_log_error_access(pb, "SRCH", base, "NULL operation"); -+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "NULL operation", 0, NULL); -+ rc = -1; -+ goto free_and_return_nolock; -+ } -+ - internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL); - flag_psearch = operation_is_flag_set(operation, OP_FLAG_PS); - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c -index 40145af2e..5f21f2f71 100644 ---- a/ldap/servers/slapd/passwd_extop.c -+++ b/ldap/servers/slapd/passwd_extop.c -@@ -727,6 +727,10 @@ parse_req_done: - */ - Operation *pb_op = NULL; - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -+ if (pb_op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "pb_op is NULL"); -+ goto free_and_return; -+ } - - operation_set_target_spec(pb_op, slapi_entry_get_sdn(targetEntry)); - slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, &pb_op->o_isroot); -diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c -index e02133abc..2db3c7fcd 100644 ---- a/ldap/servers/slapd/plugin.c -+++ b/ldap/servers/slapd/plugin.c -@@ -3625,9 +3625,11 @@ plugin_invoke_plugin_pb(struct slapdplugin *plugin, int operation, Slapi_PBlock - return PR_TRUE; - - slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -- -- -- PR_ASSERT(pb_op); -+ if (pb_op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "plugin_invoke_plugin_pb", "pb_op is NULL"); -+ PR_ASSERT(0); -+ return PR_FALSE; -+ } - - target_spec = operation_get_target_spec(pb_op); - -diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c -index 52b8df8c3..f6bbafb92 100644 ---- a/ldap/servers/slapd/plugin_internal_op.c -+++ b/ldap/servers/slapd/plugin_internal_op.c -@@ -527,6 +527,7 @@ internal_plugin_search_entry_callback(Slapi_Entry *e, void *callback_data) - this_entry = (Entry_Node *)slapi_ch_calloc(1, sizeof(Entry_Node)); - - if ((this_entry->data = slapi_entry_dup(e)) == NULL) { -+ slapi_ch_free((void**)&this_entry); - return (0); - } - -diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c -index 1bf062954..8ad268a85 100644 ---- a/ldap/servers/slapd/psearch.c -+++ b/ldap/servers/slapd/psearch.c -@@ -353,8 +353,8 @@ ps_send_results(void *arg) - if (rc) { - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", - "conn=%" PRIu64 " op=%d Error %d sending entry %s with op status %d\n", -- pb_conn->c_connid, pb_op->o_opid, -- rc, slapi_entry_get_dn_const(ec), pb_op->o_status); -+ pb_conn->c_connid, pb_op ? pb_op->o_opid: -1, -+ rc, slapi_entry_get_dn_const(ec), pb_op ? pb_op->o_status : -1); - } - } - -@@ -401,7 +401,7 @@ ps_send_results(void *arg) - - slapi_log_err(SLAPI_LOG_CONNS, "ps_send_results", - "conn=%" PRIu64 " op=%d Releasing the connection and operation\n", -- conn->c_connid, pb_op->o_opid); -+ conn->c_connid, pb_op ? pb_op->o_opid : -1); - /* Delete this op from the connection's list */ - connection_remove_operation_ext(ps->ps_pblock, conn, pb_op); - -diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c -index 0cf795b41..53464c64a 100644 ---- a/ldap/servers/slapd/pw.c -+++ b/ldap/servers/slapd/pw.c -@@ -1741,7 +1741,6 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - 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; -@@ -2229,7 +2228,7 @@ slapi_check_account_lock(Slapi_PBlock *pb, Slapi_Entry *bind_target_entry, int p - /* - * Check if the password policy has to be checked or not - */ -- if (!check_password_policy || pwpolicy->pw_lockout == 0) { -+ if (!check_password_policy || !pwpolicy || pwpolicy->pw_lockout == 0) { - goto notlocked; - } - -diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c -index 50bcbde99..602868470 100644 ---- a/ldap/servers/slapd/pw_mgmt.c -+++ b/ldap/servers/slapd/pw_mgmt.c -@@ -44,6 +44,7 @@ need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req) - char graceUserTime[16] = {0}; - Connection *pb_conn = NULL; - long t; -+ int needpw = 0; - - if (NULL == e) { - return (-1); -@@ -91,6 +92,9 @@ need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req) - slapi_ch_free_string(&passwordExpirationTime); - - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -+ if (pb_conn) { -+ needpw = pb_conn->c_needpw; -+ } - - /* Check if password has been reset */ - if (pw_exp_date == NO_TIME) { -@@ -99,7 +103,11 @@ need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req) - 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; -+ if (pb_conn){ -+ pb_conn->c_needpw = needpw = 1; -+ } else { -+ needpw = 1; -+ } - t = 0; - /* We need to include "changeafterreset" error in - * passwordpolicy response control. So, we will not be -@@ -121,7 +129,7 @@ skip: - /* 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 (needpw == 1) { - if (pwresponse_req) { - slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET); - } -@@ -150,7 +158,7 @@ skip: - slapi_mods_done(&smods); - if (pwresponse_req) { - /* check for "changeafterreset" condition */ -- if (pb_conn->c_needpw == 1) { -+ if (needpw == 1) { - slapi_pwpolicy_make_response_control(pb, -1, - ((pwpolicy->pw_gracelimit) - pwdGraceUserTime), - LDAP_PWPOLICY_CHGAFTERRESET); -@@ -182,9 +190,11 @@ skip: - 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); -+ if (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); -@@ -207,7 +217,7 @@ skip: - /* reset the expiration time to current + warning time - * and set passwordExpWarned to true - */ -- if (pb_conn->c_needpw != 1) { -+ if (needpw != 1) { - pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning); - } - -@@ -227,14 +237,14 @@ skip: - slapi_mods_done(&smods); - if (pwresponse_req) { - /* check for "changeafterreset" condition */ -- if (pb_conn->c_needpw == 1) { -+ if (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) { -+ if (needpw == 1) { - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - } else { - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t); -@@ -250,7 +260,7 @@ skip: - pw_apply_mods(sdn, &smods); - slapi_mods_done(&smods); - /* Leftover from "changeafterreset" condition */ -- if (pb_conn->c_needpw == 1) { -+ if (needpw == 1) { - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - } - /* passes checking, return 0 */ -diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c -index ce394d948..6892ccfdc 100644 ---- a/ldap/servers/slapd/result.c -+++ b/ldap/servers/slapd/result.c -@@ -1340,7 +1340,7 @@ send_specific_attrs(Slapi_Entry *e, char **attrs, Slapi_Operation *op, Slapi_PBl - attrs = attrs_ext; - } - -- for (i = 0; attrs && attrs[i] != NULL; i++) { -+ for (i = 0; my_searchattrs && attrs && attrs[i] != NULL; i++) { - char *current_type_name = attrs[i]; - Slapi_ValueSet **values = NULL; - int attr_free_flags = 0; -diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c -index 67da97148..0907c623f 100644 ---- a/ldap/servers/slapd/saslbind.c -+++ b/ldap/servers/slapd/saslbind.c -@@ -884,6 +884,11 @@ ids_sasl_check_bind(Slapi_PBlock *pb) - slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); - PR_ASSERT(pb_conn); - -+ if (pb_conn == NULL){ -+ slapi_log_err(SLAPI_LOG_ERR, "ids_sasl_check_bind", "pb_conn is NULL\n"); -+ return; -+ } -+ - PR_EnterMonitor(pb_conn->c_mutex); /* BIG LOCK */ - continuing = pb_conn->c_flags & CONN_FLAG_SASL_CONTINUE; - pb_conn->c_flags &= ~CONN_FLAG_SASL_CONTINUE; /* reset flag */ -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 002083c04..4bd8895ff 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -2335,8 +2335,9 @@ task_fixup_tombstone_thread(void *arg) - Slapi_Task *task = task_data->task; - char **base = task_data->base; - char *filter = NULL; -- int fixup_count = 0; -- int rc, i, j; -+ int32_t fixup_count = 0; -+ int32_t rc = 0; -+ int32_t i, j; - - if (!task) { - return; /* no task */ -diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c -index a0f3268da..a72de9b07 100644 ---- a/ldap/servers/slapd/util.c -+++ b/ldap/servers/slapd/util.c -@@ -746,8 +746,9 @@ normalize_mods2bvals(const LDAPMod **mods) - struct berval **mbvp = NULL; - - for (mbvp = mods[w]->mod_bvalues, -- normmbvp = normalized_mods[w]->mod_bvalues; -- mbvp && *mbvp; mbvp++, normmbvp++) { -+ normmbvp = normalized_mods[w]->mod_bvalues; -+ normmbvp && mbvp && *mbvp; mbvp++, normmbvp++) -+ { - if (is_dn_syntax) { - Slapi_DN *sdn = slapi_sdn_new_dn_byref((*mbvp)->bv_val); - if (slapi_sdn_get_dn(sdn)) { -@@ -769,8 +770,9 @@ normalize_mods2bvals(const LDAPMod **mods) - char **mvp = NULL; - - for (mvp = mods[w]->mod_values, -- normmbvp = normalized_mods[w]->mod_bvalues; -- mvp && *mvp; mvp++, normmbvp++) { -+ normmbvp = normalized_mods[w]->mod_bvalues; -+ normmbvp && mvp && *mvp; mvp++, normmbvp++) -+ { - vlen = strlen(*mvp); - - *normmbvp = -@@ -801,7 +803,7 @@ normalize_mods2bvals(const LDAPMod **mods) - PR_ASSERT(normmbvp - normalized_mods[w]->mod_bvalues <= num_values); - - /* don't forget to null terminate it */ -- if (num_values > 0) { -+ if (num_values > 0 && normmbvp) { - *normmbvp = NULL; - } - } -diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c -index 14ebc48e6..2af3ee18d 100644 ---- a/ldap/servers/slapd/valueset.c -+++ b/ldap/servers/slapd/valueset.c -@@ -121,7 +121,9 @@ valuearray_add_valuearray_fast(Slapi_Value ***vals, - j++; - } - } -- (*vals)[nvals + j] = NULL; -+ if (*vals) { -+ (*vals)[nvals + j] = NULL; -+ } - } - - void -@@ -1138,7 +1140,7 @@ slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a, Slapi_ValueSet *vs, - } - - for (size_t i = 0; i < naddvals; i++) { -- if (addvals[i] != NULL) { -+ if (addvals[i] != NULL && vs->va) { - if (passin) { - /* We consume the values */ - (vs->va)[vs->num] = addvals[i]; -@@ -1166,7 +1168,9 @@ slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a, Slapi_ValueSet *vs, - } - } - } -- (vs->va)[vs->num] = NULL; -+ if (vs->va){ -+ (vs->va)[vs->num] = NULL; -+ } - - PR_ASSERT((vs->sorted == NULL) || (vs->num < VALUESET_ARRAY_SORT_THRESHOLD) || ((vs->num >= VALUESET_ARRAY_SORT_THRESHOLD) && (vs->sorted[0] < vs->num))); - return (rc); -diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c -index 13e527188..f7c473ab1 100644 ---- a/ldap/servers/slapd/vattr.c -+++ b/ldap/servers/slapd/vattr.c -@@ -316,13 +316,19 @@ vattr_context_check(vattr_context *c) - static void - vattr_context_mark(vattr_context *c) - { -- c->vattr_context_loop_count += 1; -+ if (c) { -+ c->vattr_context_loop_count += 1; -+ } - } - - static int - vattr_context_unmark(vattr_context *c) - { -- return (c->vattr_context_loop_count -= 1); -+ if (c) { -+ return (c->vattr_context_loop_count -= 1); -+ } else { -+ return 0; -+ } - } - - /* modify the context structure on exit from a vattr sp function */ -@@ -385,13 +391,19 @@ vattr_context_grok(vattr_context **c) - static void - vattr_context_set_loop_msg_displayed(vattr_context **c) - { -- (*c)->error_displayed = 1; -+ if (c && *c){ -+ (*c)->error_displayed = 1; -+ } - } - - static int - vattr_context_is_loop_msg_displayed(vattr_context **c) - { -- return (*c)->error_displayed; -+ if (c && *c){ -+ return (*c)->error_displayed; -+ } else { -+ return 0; -+ } - } - - /* -diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c -index 5bd318df4..95cc26148 100644 ---- a/ldap/servers/snmp/main.c -+++ b/ldap/servers/snmp/main.c -@@ -21,6 +21,7 @@ - #include "ldap.h" - #include "ldif.h" - #include -+#include - #include - - static char *agentx_master = NULL; -@@ -56,16 +57,22 @@ main(int argc, char *argv[]) - char *s = getenv("DEBUG_SLEEP"); - if ((s != NULL) && isdigit(*s)) { - char *endp = NULL; -- long secs; -+ int64_t secs; - errno = 0; - -- printf("%s pid is %d\n", argv[0], getpid()); - secs = strtol(s, &endp, 10); -- if (*endp != '\0' || errno == ERANGE) { -- sleep(10); -- } else { -- sleep(secs); -+ if ( endp == s || -+ *endp != '\0' || -+ ((secs == LONG_MIN || secs == LONG_MAX) && errno == ERANGE) || -+ secs < 1 ) -+ { -+ /* Invalid value, default to 30 seconds */ -+ secs = 30; -+ } else if (secs > 3600) { -+ secs = 3600; - } -+ printf("%s pid is %d - sleeping for %ld\n", argv[0], getpid(), secs); -+ sleep(secs); - } - } - --- -2.13.6 - diff --git a/SOURCES/0057-Ticket-49287-v3-extend-csnpl-handling-to-multiple-ba.patch b/SOURCES/0057-Ticket-49287-v3-extend-csnpl-handling-to-multiple-ba.patch new file mode 100644 index 0000000..8a71d55 --- /dev/null +++ b/SOURCES/0057-Ticket-49287-v3-extend-csnpl-handling-to-multiple-ba.patch @@ -0,0 +1,795 @@ +From 6b5aa0e288f1ea5553d4dd5d220d4e5daf50a247 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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; itrepl_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 + diff --git a/SOURCES/0057-Ticket-49370-Add-all-the-password-policy-defaults-to.patch b/SOURCES/0057-Ticket-49370-Add-all-the-password-policy-defaults-to.patch deleted file mode 100644 index 239c6cb..0000000 --- a/SOURCES/0057-Ticket-49370-Add-all-the-password-policy-defaults-to.patch +++ /dev/null @@ -1,288 +0,0 @@ -From 86efa0314c59550f0660c8d143a52a57b1dffb96 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 18 Jan 2018 09:56:17 -0500 -Subject: [PATCH] Ticket 49370 - Add all the password policy defaults to a new - local policy - -Bug Description: When processing a local password policy we were not pulling - in the defaults for the "on/off" settings. This patch - addresses that. - -Fix Description: Create common default init functions for all password policies - -https://pagure.io/389-ds-base/issue/49370 - -Reviewed by: tbordaz, wibrown, and spichugi (Thanks!!!) - -(cherry picked from commit c8b388bf9f5269e1e1dc8c7c70ec8e58e825204a) ---- - .../tests/suites/password/regression_test.py | 58 +++++++++++++-- - ldap/servers/slapd/libglobs.c | 84 ++++++++++++++-------- - ldap/servers/slapd/pw.c | 29 ++------ - ldap/servers/slapd/slap.h | 2 + - 4 files changed, 113 insertions(+), 60 deletions(-) - -diff --git a/dirsrvtests/tests/suites/password/regression_test.py b/dirsrvtests/tests/suites/password/regression_test.py -index f6ee16773..800294057 100644 ---- a/dirsrvtests/tests/suites/password/regression_test.py -+++ b/dirsrvtests/tests/suites/password/regression_test.py -@@ -6,9 +6,10 @@ - # --- END COPYRIGHT BLOCK --- - # - import pytest --from lib389._constants import SUFFIX, PASSWORD -+import time -+from lib389._constants import SUFFIX, PASSWORD, DN_DM - from lib389.idm.user import UserAccounts --from lib389.utils import ldap, os, logging -+from lib389.utils import ldap, os, logging, ensure_bytes - from lib389.topologies import topology_st as topo - - DEBUGGING = os.getenv("DEBUGGING", default=False) -@@ -20,6 +21,7 @@ log = logging.getLogger(__name__) - - user_data = {'cn': 'CNpwtest1', 'sn': 'SNpwtest1', 'uid': 'UIDpwtest1', 'mail': 'MAILpwtest1@redhat.com', - 'givenname': 'GNpwtest1'} -+ - TEST_PASSWORDS = list(user_data.values()) - # Add substring/token values of "CNpwtest1" - TEST_PASSWORDS += ['CNpwtest1ZZZZ', 'ZZZZZCNpwtest1', -@@ -37,13 +39,20 @@ def passw_policy(topo, request): - """Configure password policy with PasswordCheckSyntax attribute set to on""" - - log.info('Configure Pwpolicy with PasswordCheckSyntax and nsslapd-pwpolicy-local set to on') -+ topo.standalone.simple_bind_s(DN_DM, PASSWORD) - topo.standalone.config.set('PasswordExp', 'on') - topo.standalone.config.set('PasswordCheckSyntax', 'off') - topo.standalone.config.set('nsslapd-pwpolicy-local', 'on') - - subtree = 'ou=people,{}'.format(SUFFIX) - log.info('Configure subtree password policy for {}'.format(subtree)) -- topo.standalone.subtreePwdPolicy(subtree, {'passwordchange': 'on', 'passwordCheckSyntax': 'on'}) -+ topo.standalone.subtreePwdPolicy(subtree, {'passwordchange': ensure_bytes('on'), -+ 'passwordCheckSyntax': ensure_bytes('on'), -+ 'passwordLockout': ensure_bytes('on'), -+ 'passwordResetFailureCount': ensure_bytes('3'), -+ 'passwordLockoutDuration': ensure_bytes('3'), -+ 'passwordMaxFailure': ensure_bytes('2')}) -+ time.sleep(1) - - def fin(): - log.info('Reset pwpolicy configuration settings') -@@ -76,6 +85,47 @@ def test_user(topo, request): - return tuser - - -+def test_pwp_local_unlock(topo, passw_policy, test_user): -+ """Test subtree policies use the same global default for passwordUnlock -+ -+ :id: 741a8417-5f65-4012-b9ed-87987ce3ca1b -+ :setup: Standalone instance -+ :steps: -+ 1. Test user can bind -+ 2. Bind with bad passwords to lockout account, and verify account is locked -+ 3. Wait for lockout interval, and bind with valid password -+ :expectedresults: -+ 1. Bind successful -+ 2. Entry is locked -+ 3. Entry can bind with correct password -+ """ -+ -+ log.info("Verify user can bind...") -+ test_user.bind(PASSWORD) -+ -+ log.info('Test passwordUnlock default - user should be able to reset password after lockout') -+ for i in range(0,2): -+ try: -+ test_user.bind("bad-password") -+ except ldap.INVALID_CREDENTIALS: -+ # expected -+ pass -+ except ldap.LDAPError as e: -+ log.fatal("Got unexpected failure: " + atr(e)) -+ raise e -+ -+ -+ log.info('Verify account is locked') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ test_user.bind(PASSWORD) -+ -+ log.info('Wait for lockout duration...') -+ time.sleep(4) -+ -+ log.info('Check if user can now bind with correct password') -+ test_user.bind(PASSWORD) -+ -+ - @pytest.mark.bz1465600 - @pytest.mark.parametrize("user_pasw", TEST_PASSWORDS) - def test_trivial_passw_check(topo, passw_policy, test_user, user_pasw): -@@ -143,4 +193,4 @@ if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) -- pytest.main("-s {}".format(CURRENT_FILE)) -+ pytest.main(["-s", CURRENT_FILE]) -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index 1ba30002f..c1a765aca 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -1401,6 +1401,56 @@ getFrontendConfig(void) - */ - - void -+pwpolicy_init_defaults (passwdPolicy *pw_policy) -+{ -+ pw_policy->pw_change = LDAP_ON; -+ pw_policy->pw_must_change = LDAP_OFF; -+ pw_policy->pw_syntax = LDAP_OFF; -+ pw_policy->pw_exp = LDAP_OFF; -+ pw_policy->pw_send_expiring = LDAP_OFF; -+ pw_policy->pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH; -+ pw_policy->pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS; -+ pw_policy->pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS; -+ pw_policy->pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS; -+ pw_policy->pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS; -+ pw_policy->pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS; -+ pw_policy->pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT; -+ pw_policy->pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS; -+ pw_policy->pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES; -+ pw_policy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH; -+ pw_policy->pw_maxage = SLAPD_DEFAULT_PW_MAXAGE; -+ pw_policy->pw_minage = SLAPD_DEFAULT_PW_MINAGE; -+ pw_policy->pw_warning = SLAPD_DEFAULT_PW_WARNING; -+ pw_policy->pw_history = LDAP_OFF; -+ pw_policy->pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY; -+ pw_policy->pw_lockout = LDAP_OFF; -+ pw_policy->pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE; -+ pw_policy->pw_unlock = LDAP_ON; -+ pw_policy->pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION; -+ pw_policy->pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT; -+ pw_policy->pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT; -+ pw_policy->pw_admin = NULL; -+ pw_policy->pw_admin_user = NULL; -+ pw_policy->pw_is_legacy = LDAP_ON; -+ pw_policy->pw_track_update_time = LDAP_OFF; -+} -+ -+static void -+pwpolicy_fe_init_onoff(passwdPolicy *pw_policy) -+{ -+ init_pw_change = pw_policy->pw_change; -+ init_pw_must_change = pw_policy->pw_must_change; -+ init_pw_syntax = pw_policy->pw_syntax; -+ init_pw_exp = pw_policy->pw_exp; -+ init_pw_send_expiring = pw_policy->pw_send_expiring; -+ init_pw_history = pw_policy->pw_history; -+ init_pw_lockout = pw_policy->pw_lockout; -+ init_pw_unlock = pw_policy->pw_unlock; -+ init_pw_is_legacy = pw_policy->pw_is_legacy; -+ init_pw_track_update_time = pw_policy->pw_track_update_time; -+} -+ -+void - FrontendConfig_init(void) - { - slapdFrontendConfig_t *cfg = getFrontendConfig(); -@@ -1511,41 +1561,13 @@ FrontendConfig_init(void) - * let clients abide by the LDAP standards and send us a SASL/EXTERNAL bind - * if that's what they want to do */ - init_force_sasl_external = cfg->force_sasl_external = LDAP_OFF; -- - init_readonly = cfg->readonly = LDAP_OFF; -+ -+ pwpolicy_init_defaults(&cfg->pw_policy); -+ pwpolicy_fe_init_onoff(&cfg->pw_policy); - init_pwpolicy_local = cfg->pwpolicy_local = LDAP_OFF; - init_pwpolicy_inherit_global = cfg->pwpolicy_inherit_global = LDAP_OFF; -- init_pw_change = cfg->pw_policy.pw_change = LDAP_ON; -- init_pw_must_change = cfg->pw_policy.pw_must_change = LDAP_OFF; - init_allow_hashed_pw = cfg->allow_hashed_pw = LDAP_OFF; -- init_pw_syntax = cfg->pw_policy.pw_syntax = LDAP_OFF; -- init_pw_exp = cfg->pw_policy.pw_exp = LDAP_OFF; -- init_pw_send_expiring = cfg->pw_policy.pw_send_expiring = LDAP_OFF; -- cfg->pw_policy.pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH; -- cfg->pw_policy.pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS; -- cfg->pw_policy.pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS; -- cfg->pw_policy.pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS; -- cfg->pw_policy.pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS; -- cfg->pw_policy.pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS; -- cfg->pw_policy.pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT; -- cfg->pw_policy.pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS; -- cfg->pw_policy.pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES; -- cfg->pw_policy.pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH; -- cfg->pw_policy.pw_maxage = SLAPD_DEFAULT_PW_MAXAGE; -- cfg->pw_policy.pw_minage = SLAPD_DEFAULT_PW_MINAGE; -- cfg->pw_policy.pw_warning = SLAPD_DEFAULT_PW_WARNING; -- init_pw_history = cfg->pw_policy.pw_history = LDAP_OFF; -- cfg->pw_policy.pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY; -- init_pw_lockout = cfg->pw_policy.pw_lockout = LDAP_OFF; -- cfg->pw_policy.pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE; -- init_pw_unlock = cfg->pw_policy.pw_unlock = LDAP_ON; -- cfg->pw_policy.pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION; -- cfg->pw_policy.pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT; -- cfg->pw_policy.pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT; -- cfg->pw_policy.pw_admin = NULL; -- cfg->pw_policy.pw_admin_user = NULL; -- init_pw_is_legacy = cfg->pw_policy.pw_is_legacy = LDAP_ON; -- init_pw_track_update_time = cfg->pw_policy.pw_track_update_time = LDAP_OFF; - init_pw_is_global_policy = cfg->pw_is_global_policy = LDAP_OFF; - - init_accesslog_logging_enabled = cfg->accesslog_logging_enabled = LDAP_ON; -diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c -index 53464c64a..3a545e12e 100644 ---- a/ldap/servers/slapd/pw.c -+++ b/ldap/servers/slapd/pw.c -@@ -1730,32 +1730,11 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - goto done; - } - -- /* Set the default values */ -- pwdpolicy->pw_mintokenlength = SLAPD_DEFAULT_PW_MINTOKENLENGTH; -- pwdpolicy->pw_minlength = SLAPD_DEFAULT_PW_MINLENGTH; -- pwdpolicy->pw_mindigits = SLAPD_DEFAULT_PW_MINDIGITS; -- pwdpolicy->pw_minalphas = SLAPD_DEFAULT_PW_MINALPHAS; -- pwdpolicy->pw_minuppers = SLAPD_DEFAULT_PW_MINUPPERS; -- pwdpolicy->pw_minlowers = SLAPD_DEFAULT_PW_MINLOWERS; -- pwdpolicy->pw_minspecials = SLAPD_DEFAULT_PW_MINSPECIALS; -- pwdpolicy->pw_min8bit = SLAPD_DEFAULT_PW_MIN8BIT; -- pwdpolicy->pw_maxrepeats = SLAPD_DEFAULT_PW_MAXREPEATS; -- pwdpolicy->pw_mincategories = SLAPD_DEFAULT_PW_MINCATEGORIES; -- pwdpolicy->pw_maxage = SLAPD_DEFAULT_PW_MAXAGE; -- pwdpolicy->pw_minage = SLAPD_DEFAULT_PW_MINAGE; -- pwdpolicy->pw_warning = SLAPD_DEFAULT_PW_WARNING; -- pwdpolicy->pw_inhistory = SLAPD_DEFAULT_PW_INHISTORY; -- pwdpolicy->pw_maxfailure = SLAPD_DEFAULT_PW_MAXFAILURE; -- pwdpolicy->pw_lockduration = SLAPD_DEFAULT_PW_LOCKDURATION; -- pwdpolicy->pw_resetfailurecount = SLAPD_DEFAULT_PW_RESETFAILURECOUNT; -- pwdpolicy->pw_gracelimit = SLAPD_DEFAULT_PW_GRACELIMIT; -- -- /* set the default passwordLegacyPolicy setting */ -- pwdpolicy->pw_is_legacy = 1; -- -- /* set passwordTrackUpdateTime */ -- pwdpolicy->pw_track_update_time = slapdFrontendConfig->pw_policy.pw_track_update_time; -+ /* Set the default values (from libglobs.c) */ -+ pwpolicy_init_defaults(pwdpolicy); -+ pwdpolicy->pw_storagescheme = slapdFrontendConfig->pw_storagescheme; - -+ /* Set the defined values now */ - for (slapi_entry_first_attr(pw_entry, &attr); attr; - slapi_entry_next_attr(pw_entry, attr, &attr)) { - slapi_attr_get_type(attr, &attr_name); -diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h -index 08754d8fb..f6fc374a4 100644 ---- a/ldap/servers/slapd/slap.h -+++ b/ldap/servers/slapd/slap.h -@@ -1773,6 +1773,8 @@ typedef struct passwordpolicyarray - Slapi_DN **pw_admin_user; - } passwdPolicy; - -+void pwpolicy_init_defaults (passwdPolicy *pw_policy); -+ - Slapi_PBlock *slapi_pblock_clone(Slapi_PBlock *pb); /* deprecated */ - - passwdPolicy *slapi_pblock_get_pwdpolicy(Slapi_PBlock *pb); --- -2.13.6 - diff --git a/SOURCES/0058-Ticket-49336-SECURITY-Locked-account-provides-differ.patch b/SOURCES/0058-Ticket-49336-SECURITY-Locked-account-provides-differ.patch new file mode 100644 index 0000000..c110f0a --- /dev/null +++ b/SOURCES/0058-Ticket-49336-SECURITY-Locked-account-provides-differ.patch @@ -0,0 +1,201 @@ +From 95b39e29361812a62f2e038c89a88d717c82794e Mon Sep 17 00:00:00 2001 +From: William Brown +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 +--- + .../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 + diff --git a/SOURCES/0058-Ticket-49541-repl-config-should-not-allow-rid-65535-.patch b/SOURCES/0058-Ticket-49541-repl-config-should-not-allow-rid-65535-.patch deleted file mode 100644 index 63a6136..0000000 --- a/SOURCES/0058-Ticket-49541-repl-config-should-not-allow-rid-65535-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 38ca528af83f1874a79ad6744215bd4af1404414 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 18 Jan 2018 13:17:08 -0500 -Subject: [PATCH] Ticket 49541 - repl config should not allow rid 65535 for - masters - -Description: Reject adding a replica config entry with a rid of 65535 or higher, - and prevent setting master's rid to 65535 or higher. - -https://pagure.io/389-ds-base/issue/49541 - -Reviewed by: mreynolds(one line commit rule) - -(cherry picked from commit ebb00a4180693225cf3c2f4aced54dc33141fa77) ---- - dirsrvtests/tests/suites/replication/replica_config_test.py | 9 +++++---- - ldap/servers/plugins/replication/repl5_replica.c | 2 +- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py -index 50ea2ece9..143a12479 100644 ---- a/dirsrvtests/tests/suites/replication/replica_config_test.py -+++ b/dirsrvtests/tests/suites/replication/replica_config_test.py -@@ -24,7 +24,7 @@ replica_dict = {'objectclass': 'top nsDS5Replica'.split(), - 'nsDS5ReplicaRoot': 'dc=example,dc=com', - 'nsDS5ReplicaType': '3', - 'nsDS5Flags': '1', -- 'nsDS5ReplicaId': '65535', -+ 'nsDS5ReplicaId': '65534', - 'nsds5ReplicaPurgeDelay': '604800', - 'nsDS5ReplicaBindDN': 'cn=u', - 'cn': 'replica'} -@@ -42,7 +42,7 @@ agmt_dict = {'objectClass': 'top nsDS5ReplicationAgreement'.split(), - - repl_add_attrs = [('nsDS5ReplicaType', '-1', '4', overflow, notnum, '1'), - ('nsDS5Flags', '-1', '2', overflow, notnum, '1'), -- ('nsDS5ReplicaId', '0', '65536', overflow, notnum, '1'), -+ ('nsDS5ReplicaId', '0', '65535', overflow, notnum, '1'), - ('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'), - ('nsDS5ReplicaBindDnGroupCheckInterval', '-2', too_big, overflow, notnum, '1'), - ('nsds5ReplicaTombstonePurgeInterval', '-2', too_big, overflow, notnum, '1'), -@@ -60,7 +60,8 @@ repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'), - ('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'), - ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')] - --agmt_attrs = [('nsds5ReplicaPort', '0', '65536', overflow, notnum, '389'), -+agmt_attrs = [ -+ ('nsds5ReplicaPort', '0', '65535', overflow, notnum, '389'), - ('nsds5ReplicaTimeout', '-1', too_big, overflow, notnum, '6'), - ('nsds5ReplicaBusyWaitTime', '-1', too_big, overflow, notnum, '6'), - ('nsds5ReplicaSessionPauseTime', '-1', too_big, overflow, notnum, '6'), -@@ -393,5 +394,5 @@ if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode - CURRENT_FILE = os.path.realpath(__file__) -- pytest.main("-s %s" % CURRENT_FILE) -+ pytest.main(["-s", CURRENT_FILE]) - -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index e75807a62..bdb8a5167 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -1988,7 +1988,7 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext) - r->repl_type == REPLICA_TYPE_PRIMARY) { - if ((val = slapi_entry_attr_get_charptr(e, attr_replicaId))) { - int64_t rid; -- if (repl_config_valid_num(attr_replicaId, val, 1, 65535, &rc, errormsg, &rid) != 0) { -+ if (repl_config_valid_num(attr_replicaId, val, 1, 65534, &rc, errormsg, &rid) != 0) { - slapi_ch_free_string(&val); - return -1; - } --- -2.13.6 - diff --git a/SOURCES/0059-CVE-2017-15134-crash-in-slapi_filter_sprintf.patch b/SOURCES/0059-CVE-2017-15134-crash-in-slapi_filter_sprintf.patch deleted file mode 100644 index 8d43a80..0000000 --- a/SOURCES/0059-CVE-2017-15134-crash-in-slapi_filter_sprintf.patch +++ /dev/null @@ -1,111 +0,0 @@ -From cb008bcace2510f157ccec2df4e5ff254513b7c4 Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Mon, 15 Jan 2018 10:24:41 +0100 -Subject: [PATCH] CVE 2017-15134 - crash in slapi_filter_sprintf - -Signed-off-by: Mark Reynolds ---- - ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++----- - 1 file changed, 31 insertions(+), 5 deletions(-) - -diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c -index a72de9b07..ddb2cc899 100644 ---- a/ldap/servers/slapd/util.c -+++ b/ldap/servers/slapd/util.c -@@ -238,9 +238,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ]) - struct filter_ctx - { - char *buf; -- char attr[ATTRSIZE]; -+ char *attr; - int attr_position; - int attr_found; -+ size_t attr_size; - int buf_size; - int buf_len; - int next_arg_needs_esc_norm; -@@ -279,7 +280,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) - * Start collecting the attribute name so we can use the correct - * syntax normalization func. - */ -- if (ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)) { -+ if (ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) { - if (ctx->attr[0] == '\0') { - if (strstr(val, "=")) { - /* we have an attr we need to record */ -@@ -293,6 +294,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) - * attr with val. The next pass should be '=', otherwise we will - * reset it. - */ -+ if (slen > ctx->attr_size) { -+ if (ctx->attr_size == ATTRSIZE) { -+ ctx->attr = slapi_ch_calloc(sizeof(char), slen+1); -+ } else { -+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1)); -+ } -+ ctx->attr_size = slen+1; -+ } - memcpy(ctx->attr, val, slen); - ctx->attr_position = slen; - } -@@ -302,9 +311,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) - } else { - if (special_attr_char(val[0])) { - /* this is not an attribute, we should not be collecting this, reset everything */ -- memset(ctx->attr, '\0', ATTRSIZE); -+ memset(ctx->attr, '\0', ctx->attr_size); - ctx->attr_position = 0; - } else { -+ /* we can be adding char by char and overrun allocated size */ -+ if (ctx->attr_position >= ctx->attr_size) { -+ if (ctx->attr_size == ATTRSIZE) { -+ char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE); -+ memcpy(ctxattr, ctx->attr, ctx->attr_size); -+ ctx->attr = ctxattr; -+ } else { -+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE)); -+ } -+ ctx->attr_size = ctx->attr_size + ATTRSIZE; -+ } - memcpy(ctx->attr + ctx->attr_position, val, 1); - ctx->attr_position++; - } -@@ -377,7 +397,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) - ctx->next_arg_needs_esc_norm = 0; - ctx->attr_found = 0; - ctx->attr_position = 0; -- memset(ctx->attr, '\0', ATTRSIZE); -+ memset(ctx->attr, '\0', ctx->attr_size); - slapi_ch_free_string(&buf); - - return filter_len; -@@ -416,12 +436,14 @@ slapi_filter_sprintf(const char *fmt, ...) - { - struct filter_ctx ctx = {0}; - va_list args; -+ char attr_static[ATTRSIZE] = {0}; - char *buf; - int rc; - - buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1); - ctx.buf = buf; -- memset(ctx.attr, '\0', ATTRSIZE); -+ ctx.attr = attr_static; -+ ctx.attr_size = ATTRSIZE; - ctx.attr_position = 0; - ctx.attr_found = 0; - ctx.buf_len = FILTER_BUF; -@@ -438,6 +460,10 @@ slapi_filter_sprintf(const char *fmt, ...) - } - va_end(args); - -+ if (ctx.attr_size > ATTRSIZE) { -+ slapi_ch_free_string(&ctx.attr); -+ } -+ - return ctx.buf; - } - --- -2.13.6 - diff --git a/SOURCES/0059-Ticket-49298-force-sync-on-shutdown.patch b/SOURCES/0059-Ticket-49298-force-sync-on-shutdown.patch new file mode 100644 index 0000000..4d900fb --- /dev/null +++ b/SOURCES/0059-Ticket-49298-force-sync-on-shutdown.patch @@ -0,0 +1,177 @@ +From ba30cc562f5ebd58955502a19edbf9720a45b655 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + ++#include /* 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 + diff --git a/SOURCES/0060-Ticket-49334-fix-backup-restore-if-changelog-exists.patch b/SOURCES/0060-Ticket-49334-fix-backup-restore-if-changelog-exists.patch new file mode 100644 index 0000000..25d4010 --- /dev/null +++ b/SOURCES/0060-Ticket-49334-fix-backup-restore-if-changelog-exists.patch @@ -0,0 +1,37 @@ +From c903f66194f04e97fc684f5a9654cedb27530931 Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +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 + diff --git a/SOURCES/0060-Ticket-49534-Fix-coverity-regression.patch b/SOURCES/0060-Ticket-49534-Fix-coverity-regression.patch deleted file mode 100644 index b5adec3..0000000 --- a/SOURCES/0060-Ticket-49534-Fix-coverity-regression.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 3c605035eff49e603c8e4a4c0886499913924529 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 24 Jan 2018 14:24:08 -0500 -Subject: [PATCH] Ticket 49534 - Fix coverity regression - -Description: In automembers plugin a free was in the wrong spot - which later led to a double free for the "rule". - -https://pagure.io/389-ds-base/issue/49534 - -Reviewed by: mreynolds (one line commit rule) - -(cherry picked from commit b3768e602fdfc2ea1fc645b17ad61c8592ab87fa) ---- - ldap/servers/plugins/automember/automember.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c -index cbd25915a..c91aa4e8e 100644 ---- a/ldap/servers/plugins/automember/automember.c -+++ b/ldap/servers/plugins/automember/automember.c -@@ -1117,11 +1117,11 @@ automember_parse_regex_entry(struct configEntry *config, Slapi_Entry *e) - break; - } - } -+ automember_free_regex_rule(rule); - } else { - /* Add to head of list */ - PR_INSERT_LINK(&(rule->list), (PRCList *)config->exclusive_rules); - } -- automember_free_regex_rule(rule); - } else { - slapi_log_err(SLAPI_LOG_ERR, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "automember_parse_regex_entry - Skipping invalid exclusive " --- -2.13.6 - diff --git a/SOURCES/0061-Ticket-49356-mapping-tree-crash-can-occur-during-tot.patch b/SOURCES/0061-Ticket-49356-mapping-tree-crash-can-occur-during-tot.patch new file mode 100644 index 0000000..23540e5 --- /dev/null +++ b/SOURCES/0061-Ticket-49356-mapping-tree-crash-can-occur-during-tot.patch @@ -0,0 +1,502 @@ +From b0954a5df7841330732a5ab532c528a68cf380cf Mon Sep 17 00:00:00 2001 +From: William Brown +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 + diff --git a/SOURCES/0061-Ticket-49541-Replica-ID-config-validation-fix.patch b/SOURCES/0061-Ticket-49541-Replica-ID-config-validation-fix.patch deleted file mode 100644 index 5520757..0000000 --- a/SOURCES/0061-Ticket-49541-Replica-ID-config-validation-fix.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d39be97021f273548957a9f26ca35d5faab20318 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 29 Jan 2018 21:13:16 -0500 -Subject: [PATCH] Ticket 49541 - Replica ID config validation fix - -Description: Is is possible to set the replica ID to 65535 with a modify - operation, which is reserved for hubs/consumers. - -https://pagure.io/389-ds-base/issue/49541 - -Reviewed by: mreynolds (one line commit rule) ---- - ldap/servers/plugins/replication/repl5_replica_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c -index bda333362..ea430d9a4 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_config.c -+++ b/ldap/servers/plugins/replication/repl5_replica_config.c -@@ -421,7 +421,7 @@ replica_config_modify(Slapi_PBlock *pb, - } - } else if (strcasecmp(config_attr, attr_replicaId) == 0) { - int64_t rid = 0; -- if (repl_config_valid_num(config_attr, config_attr_value, 1, 65535, returncode, errortext, &rid) == 0) { -+ if (repl_config_valid_num(config_attr, config_attr_value, 1, 65534, returncode, errortext, &rid) == 0) { - slapi_ch_free_string(&new_repl_id); - new_repl_id = slapi_ch_strdup(config_attr_value); - } else { --- -2.13.6 - diff --git a/SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch b/SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch new file mode 100644 index 0000000..9b21655 --- /dev/null +++ b/SOURCES/0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch @@ -0,0 +1,1041 @@ +From 2975f68e139169ee2d2259cfbbb2a15b54dc3724 Mon Sep 17 00:00:00 2001 +From: William Brown +Date: Wed, 26 Jul 2017 11:01:49 +1000 +Subject: [PATCH] Ticket 49330 - Improve ndn cache performance 1.3.6 + +Backport from 1.3.7 master. + +Bug Description: Normalised DN's are a costly process to update +and maintain. As a result, a normalised DN cache was created. Yet +it was never able to perform well. In some datasets with large sets +of dn attr types, the NDN cache actively hurt performance. + +The issue stemmed from 3 major issues in the design of the NDN +cache. + +First, it is a global cache which means it exists behind +a rwlock. This causes delay as threads wait behind the lock +to access or update the cache (especially on a miss). + +Second, the cache was limited to 4073 buckets. Despite the fact +that a prime number on a hash causes a skew in distribution, +this was in an NSPR hash - which does not grow dynamically, +rather devolving a bucket to a linked list. AS a result, once you +passed ~3000 your lookup performance would degrade rapidly to O(1) + +Finally, the cache's lru policy did not evict least used - it +evicted the 10,000 least used. So if you tuned your cache +to match the NSPR map, every inclusion that would trigger a +delete of old values would effectively empty your cache. ON bigger +set sizes, this has to walk the map (at O(1)) to clean 10,000 +elements. + +Premature optimisation strikes again .... + +Fix Description: Throw it out. Rewrite. We now use a hash +algo that has proper distribution across a set. The hash +sizes slots to a power of two. Finally, each thread has +a private cache rather than shared which completely eliminates +a lock contention and even NUMA performance issues. + +Interestingly this fix should have improvements for DB +imports, memberof and refint performance and more. + +Some testing has shown in simple search workloads a 10% +improvement in throughput, and on complex searches a 47x +improvement. + +https://pagure.io/389-ds-base/issue/49330 + +Author: wibrown + +Review by: lkrispen, tbordaz +--- + ldap/servers/slapd/back-ldbm/monitor.c | 11 +- + ldap/servers/slapd/dn.c | 809 +++++++++++++++++++++------------ + ldap/servers/slapd/slapi-private.h | 2 +- + 3 files changed, 527 insertions(+), 295 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/monitor.c b/ldap/servers/slapd/back-ldbm/monitor.c +index c58b069..aa7d709 100644 +--- a/ldap/servers/slapd/back-ldbm/monitor.c ++++ b/ldap/servers/slapd/back-ldbm/monitor.c +@@ -43,6 +43,9 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + PRUint64 hits, tries; + long nentries, maxentries, count; + size_t size, maxsize; ++ size_t thread_size; ++ size_t evicts; ++ size_t slots; + /* NPCTE fix for bugid 544365, esc 0. <04-Jul-2001> */ + struct stat astat; + /* end of NPCTE fix for bugid 544365 */ +@@ -118,7 +121,7 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + } + /* normalized dn cache stats */ + if(ndn_cache_started()){ +- ndn_cache_get_stats(&hits, &tries, &size, &maxsize, &count); ++ ndn_cache_get_stats(&hits, &tries, &size, &maxsize, &thread_size, &evicts, &slots, &count); + sprintf(buf, "%" PRIu64, tries); + MSET("normalizedDnCacheTries"); + sprintf(buf, "%" PRIu64, hits); +@@ -127,6 +130,8 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + MSET("normalizedDnCacheMisses"); + sprintf(buf, "%lu", (unsigned long)(100.0*(double)hits / (double)(tries > 0 ? tries : 1))); + MSET("normalizedDnCacheHitRatio"); ++ sprintf(buf, "%"PRIu64, evicts); ++ MSET("NormalizedDnCacheEvictions"); + sprintf(buf, "%lu", (long unsigned int)size); + MSET("currentNormalizedDnCacheSize"); + if(maxsize == 0){ +@@ -135,6 +140,10 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e, + sprintf(buf, "%lu", (long unsigned int)maxsize); + } + MSET("maxNormalizedDnCacheSize"); ++ sprintf(buf, "%"PRIu64, thread_size); ++ MSET("NormalizedDnCacheThreadSize"); ++ sprintf(buf, "%"PRIu64, slots); ++ MSET("NormalizedDnCacheThreadSlots"); + sprintf(buf, "%ld", count); + MSET("currentNormalizedDnCacheCount"); + } +diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c +index fa3909f..9cb3e7b 100644 +--- a/ldap/servers/slapd/dn.c ++++ b/ldap/servers/slapd/dn.c +@@ -22,6 +22,24 @@ + #include "slap.h" + #include + ++#include ++#include /* for size_t */ ++ ++#if defined(HAVE_SYS_ENDIAN_H) ++#include ++#elif defined(HAVE_ENDIAN_H) ++#include ++#else ++#error platform header for endian detection not found. ++#endif ++ ++/* See: http://sourceforge.net/p/predef/wiki/Endianness/ */ ++#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN ++#define _le64toh(x) ((uint64_t)(x)) ++#else ++#define _le64toh(x) le64toh(x) ++#endif ++ + #undef SDN_DEBUG + + static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp, +@@ -33,52 +51,89 @@ static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape ); + static int does_cn_uses_dn_syntax_in_dns(char *type, char *dn); + + /* normalized dn cache related definitions*/ +-struct +-ndn_cache_lru +-{ +- struct ndn_cache_lru *prev; +- struct ndn_cache_lru *next; +- char *key; +-}; +- +-struct +-ndn_cache_ctx +-{ +- struct ndn_cache_lru *head; +- struct ndn_cache_lru *tail; ++struct ndn_cache_stats { + Slapi_Counter *cache_hits; + Slapi_Counter *cache_tries; +- Slapi_Counter *cache_misses; +- size_t cache_size; +- size_t cache_max_size; +- long cache_count; ++ Slapi_Counter *cache_count; ++ Slapi_Counter *cache_size; ++ Slapi_Counter *cache_evicts; ++ size_t max_size; ++ size_t thread_max_size; ++ size_t slots; + }; + +-struct +-ndn_hash_val +-{ ++struct ndn_cache_value { ++ size_t size; ++ size_t slot; ++ char *dn; + char *ndn; +- size_t len; +- int size; +- struct ndn_cache_lru *lru_node; /* used to speed up lru shuffling */ ++ struct ndn_cache_value *next; ++ struct ndn_cache_value *prev; ++ struct ndn_cache_value *child; ++}; ++ ++/* ++ * This uses a similar alloc trick to IDList to keep ++ * The amount of derefs small. ++ */ ++struct ndn_cache { ++ /* ++ * We keep per thread stats and flush them occasionally ++ */ ++ size_t max_size; ++ /* Need to track this because we need to provide diffs to counter */ ++ size_t last_count; ++ size_t count; ++ /* Number of ops */ ++ size_t tries; ++ /* hit vs miss. in theroy miss == tries - hits.*/ ++ size_t hits; ++ /* How many values we kicked out */ ++ size_t evicts; ++ /* Need to track this because we need to provide diffs to counter */ ++ size_t last_size; ++ size_t size; ++ ++ size_t slots; ++ /* ++ * This is used by siphash to prevent hash bugket attacks ++ */ ++ char key[16]; ++ ++ struct ndn_cache_value *head; ++ struct ndn_cache_value *tail; ++ struct ndn_cache_value *table[1]; + }; + +-#define NDN_FLUSH_COUNT 10000 /* number of DN's to remove when cache fills up */ +-#define NDN_MIN_COUNT 1000 /* the minimum number of DN's to keep in the cache */ +-#define NDN_CACHE_BUCKETS 2053 /* prime number */ ++/* ++ * This means we need 1 MB minimum per thread ++ * ++ */ ++#define NDN_CACHE_MINIMUM_CAPACITY 1048576 ++/* ++ * This helps us define the number of hashtable slots ++ * to create. We assume an average DN is 64 chars long ++ * This way we end up we a ht entry of: ++ * 8 bytes: from the table pointing to us. ++ * 8 bytes: next ptr ++ * 8 bytes: prev ptr ++ * 8 bytes + 64: dn ++ * 8 bytes + 64: ndn itself. ++ * This gives us 168 bytes. In theory this means ++ * 6241 entries, but we have to clamp this to a power of ++ * two, so we have 8192 slots. In reality, dns may be ++ * shorter *and* the dn may be the same as the ndn ++ * so we *may* store more ndns that this. Again, a good reason ++ * to round the ht size up! ++ */ ++#define NDN_ENTRY_AVG_SIZE 168 ++/* ++ * After how many operations do we sync our per-thread stats. ++ */ ++#define NDN_STAT_COMMIT_FREQUENCY 256 + +-static PLHashNumber ndn_hash_string(const void *key); + static int ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc); +-static void ndn_cache_update_lru(struct ndn_cache_lru **node); + static void ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len); +-static void ndn_cache_delete(char *dn); +-static void ndn_cache_flush(void); +-static void ndn_cache_free(void); +-static int ndn_started = 0; +-static PRLock *lru_lock = NULL; +-static Slapi_RWLock *ndn_cache_lock = NULL; +-static struct ndn_cache_ctx *ndn_cache = NULL; +-static PLHashTable *ndn_cache_hashtable = NULL; + + #define ISBLANK(c) ((c) == ' ') + #define ISBLANKSTR(s) (((*(s)) == '2') && (*((s)+1) == '0')) +@@ -2768,166 +2823,408 @@ slapi_sdn_get_size(const Slapi_DN *sdn) + * + */ + ++/* ++ Copyright (c) 2013 Marek Majkowski ++ ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be included in ++ all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ THE SOFTWARE. ++ ++ ++ Original location: ++ https://github.com/majek/csiphash/ ++ ++ Solution inspired by code from: ++ Samuel Neves (supercop/crypto_auth/siphash24/little) ++ djb (supercop/crypto_auth/siphash24/little2) ++ Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c) ++*/ ++ ++#define ROTATE(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) ++ ++#define HALF_ROUND(a, b, c, d, s, t) \ ++ a += b; \ ++ c += d; \ ++ b = ROTATE(b, s) ^ a; \ ++ d = ROTATE(d, t) ^ c; \ ++ a = ROTATE(a, 32); ++ ++#define ROUND(v0, v1, v2, v3) \ ++ HALF_ROUND(v0, v1, v2, v3, 13, 16); \ ++ HALF_ROUND(v2, v1, v0, v3, 17, 21) ++ ++#define cROUND(v0, v1, v2, v3) \ ++ ROUND(v0, v1, v2, v3) ++ ++#define dROUND(v0, v1, v2, v3) \ ++ ROUND(v0, v1, v2, v3); \ ++ ROUND(v0, v1, v2, v3); \ ++ ROUND(v0, v1, v2, v3) ++ ++ ++static uint64_t ++sds_siphash13(const void *src, size_t src_sz, const char key[16]) ++{ ++ const uint64_t *_key = (uint64_t *)key; ++ uint64_t k0 = _le64toh(_key[0]); ++ uint64_t k1 = _le64toh(_key[1]); ++ uint64_t b = (uint64_t)src_sz << 56; ++ const uint64_t *in = (uint64_t *)src; ++ ++ uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; ++ uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; ++ uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; ++ uint64_t v3 = k1 ^ 0x7465646279746573ULL; ++ ++ while (src_sz >= 8) { ++ uint64_t mi = _le64toh(*in); ++ in += 1; ++ src_sz -= 8; ++ v3 ^= mi; ++ // cround ++ cROUND(v0, v1, v2, v3); ++ v0 ^= mi; ++ } ++ ++ uint64_t t = 0; ++ uint8_t *pt = (uint8_t *)&t; ++ uint8_t *m = (uint8_t *)in; ++ ++ switch (src_sz) { ++ case 7: ++ pt[6] = m[6]; /* FALLTHRU */ ++ case 6: ++ pt[5] = m[5]; /* FALLTHRU */ ++ case 5: ++ pt[4] = m[4]; /* FALLTHRU */ ++ case 4: ++ *((uint32_t *)&pt[0]) = *((uint32_t *)&m[0]); ++ break; ++ case 3: ++ pt[2] = m[2]; /* FALLTHRU */ ++ case 2: ++ pt[1] = m[1]; /* FALLTHRU */ ++ case 1: ++ pt[0] = m[0]; /* FALLTHRU */ ++ } ++ b |= _le64toh(t); ++ ++ v3 ^= b; ++ // cround ++ cROUND(v0, v1, v2, v3); ++ v0 ^= b; ++ v2 ^= 0xff; ++ // dround ++ dROUND(v0, v1, v2, v3); ++ return (v0 ^ v1) ^ (v2 ^ v3); ++} ++ ++static pthread_key_t ndn_cache_key; ++static pthread_once_t ndn_cache_key_once = PTHREAD_ONCE_INIT; ++static struct ndn_cache_stats t_cache_stats = {0}; + /* +- * Hashing function using Bernstein's method ++ * WARNING: For some reason we try to use the NDN cache *before* ++ * we have a chance to configure it. As a result, we need to rely ++ * on a trick in the way we start, that we start in one thread ++ * so we can manipulate ints as though they were atomics, then ++ * we start in *one* thread, so it's set, then when threads ++ * fork the get barriers, so we can go from there. However we *CANNOT* ++ * change this at runtime without expensive atomics per op, so lets ++ * not bother until we improve libglobs to be COW. + */ +-static PLHashNumber +-ndn_hash_string(const void *key) +-{ +- PLHashNumber hash = 5381; +- unsigned char *x = (unsigned char *)key; +- int c; ++static int32_t ndn_enabled = 0; ++ ++static struct ndn_cache * ++ndn_thread_cache_create(size_t thread_max_size, size_t slots) { ++ size_t t_cache_size = sizeof(struct ndn_cache) + (slots * sizeof(struct ndn_cache_value *)); ++ struct ndn_cache *t_cache = (struct ndn_cache *)slapi_ch_calloc(1, t_cache_size); ++ ++ t_cache->max_size = thread_max_size; ++ t_cache->slots = slots; + +- while ((c = *x++)){ +- hash = ((hash << 5) + hash) ^ c; ++ return t_cache; ++} ++ ++static void ++ndn_thread_cache_commit_status(struct ndn_cache *t_cache) { ++ /* ++ * Every so often we commit these atomically. We do this infrequently ++ * to avoid the costly atomics. ++ */ ++ if (t_cache->tries % NDN_STAT_COMMIT_FREQUENCY == 0) { ++ /* We can just add tries and hits. */ ++ slapi_counter_add(t_cache_stats.cache_evicts, t_cache->evicts); ++ slapi_counter_add(t_cache_stats.cache_tries, t_cache->tries); ++ slapi_counter_add(t_cache_stats.cache_hits, t_cache->hits); ++ t_cache->hits = 0; ++ t_cache->tries = 0; ++ t_cache->evicts = 0; ++ /* Count and size need diff */ ++ int64_t diff = (t_cache->size - t_cache->last_size); ++ if (diff > 0) { ++ // We have more .... ++ slapi_counter_add(t_cache_stats.cache_size, (uint64_t)diff); ++ } else if (diff < 0) { ++ slapi_counter_subtract(t_cache_stats.cache_size, (uint64_t)llabs(diff)); ++ } ++ t_cache->last_size = t_cache->size; ++ ++ diff = (t_cache->count - t_cache->last_count); ++ if (diff > 0) { ++ // We have more .... ++ slapi_counter_add(t_cache_stats.cache_count, (uint64_t)diff); ++ } else if (diff < 0) { ++ slapi_counter_subtract(t_cache_stats.cache_count, (uint64_t)llabs(diff)); ++ } ++ t_cache->last_count = t_cache->count; ++ ++ } ++} ++ ++static void ++ndn_thread_cache_value_destroy(struct ndn_cache *t_cache, struct ndn_cache_value *v) { ++ /* Update stats */ ++ t_cache->size = t_cache->size - v->size; ++ t_cache->count--; ++ t_cache->evicts++; ++ ++ if (v == t_cache->head) { ++ t_cache->head = v->prev; ++ } ++ if (v == t_cache->tail) { ++ t_cache->tail = v->next; ++ } ++ ++ /* Cut the node out. */ ++ if (v->next != NULL) { ++ v->next->prev = v->prev; ++ } ++ if (v->prev != NULL) { ++ v->prev->next = v->next; ++ } ++ /* Set the pointer in the table to NULL */ ++ /* Now see if we were in a list */ ++ struct ndn_cache_value *slot_node = t_cache->table[v->slot]; ++ if (slot_node == v) { ++ t_cache->table[v->slot] = v->child; ++ } else { ++ struct ndn_cache_value *former_slot_node = NULL; ++ do { ++ former_slot_node = slot_node; ++ slot_node = slot_node->child; ++ } while(slot_node != v); ++ /* Okay, now slot_node is us, and former is our parent */ ++ former_slot_node->child = v->child; ++ } ++ ++ slapi_ch_free((void **)&(v->dn)); ++ slapi_ch_free((void **)&(v->ndn)); ++ slapi_ch_free((void **)&v); ++} ++ ++static void ++ndn_thread_cache_destroy(void *v_cache) { ++ struct ndn_cache *t_cache = (struct ndn_cache *)v_cache; ++ /* ++ * FREE ALL THE NODES!!! ++ */ ++ struct ndn_cache_value *node = t_cache->tail; ++ struct ndn_cache_value *next_node = NULL; ++ while (node) { ++ next_node = node->next; ++ ndn_thread_cache_value_destroy(t_cache, node); ++ node = next_node; ++ } ++ slapi_ch_free((void **)&t_cache); ++} ++ ++static void ++ndn_cache_key_init() { ++ if (pthread_key_create(&ndn_cache_key, ndn_thread_cache_destroy) != 0) { ++ /* Log a scary warning? */ ++ slapi_log_err(SLAPI_LOG_ERR, "ndn_cache_init", "Failed to create pthread key, aborting.\n"); + } +- return hash; + } + + void + ndn_cache_init() + { +- if(!config_get_ndn_cache_enabled() || ndn_started){ ++ ndn_enabled = config_get_ndn_cache_enabled(); ++ if (ndn_enabled == 0) { ++ /* ++ * Don't configure the keys or anything, need a restart ++ * to enable. We'll just never use ndn cache in this ++ * run. ++ */ + return; + } +- ndn_cache_hashtable = PL_NewHashTable( NDN_CACHE_BUCKETS, ndn_hash_string, PL_CompareStrings, PL_CompareValues, 0, 0); +- ndn_cache = (struct ndn_cache_ctx *)slapi_ch_malloc(sizeof(struct ndn_cache_ctx)); +- ndn_cache->cache_max_size = config_get_ndn_cache_size(); +- ndn_cache->cache_hits = slapi_counter_new(); +- ndn_cache->cache_tries = slapi_counter_new(); +- ndn_cache->cache_misses = slapi_counter_new(); +- ndn_cache->cache_count = 0; +- ndn_cache->cache_size = sizeof(struct ndn_cache_ctx) + sizeof(PLHashTable) + sizeof(PLHashTable); +- ndn_cache->head = NULL; +- ndn_cache->tail = NULL; +- ndn_started = 1; +- if ( NULL == ( lru_lock = PR_NewLock()) || NULL == ( ndn_cache_lock = slapi_new_rwlock())) { +- ndn_cache_destroy(); +- slapi_log_err(SLAPI_LOG_ERR, "ndn_cache_init", "Failed to create locks. Disabling cache.\n" ); ++ ++ /* Create the pthread key */ ++ (void)pthread_once(&ndn_cache_key_once, ndn_cache_key_init); ++ ++ /* Create the global stats. */ ++ t_cache_stats.max_size = config_get_ndn_cache_size(); ++ t_cache_stats.cache_evicts = slapi_counter_new(); ++ t_cache_stats.cache_tries = slapi_counter_new(); ++ t_cache_stats.cache_hits = slapi_counter_new(); ++ t_cache_stats.cache_count = slapi_counter_new(); ++ t_cache_stats.cache_size = slapi_counter_new(); ++ /* Get thread numbers and calc the per thread size */ ++ int32_t maxthreads = (int32_t)config_get_threadnumber(); ++ size_t tentative_size = t_cache_stats.max_size / maxthreads; ++ if (tentative_size < NDN_CACHE_MINIMUM_CAPACITY) { ++ tentative_size = NDN_CACHE_MINIMUM_CAPACITY; ++ t_cache_stats.max_size = NDN_CACHE_MINIMUM_CAPACITY * maxthreads; ++ } ++ t_cache_stats.thread_max_size = tentative_size; ++ ++ /* ++ * Slots *must* be a power of two, even if the number of entries ++ * we store will be *less* than this. ++ */ ++ size_t possible_elements = tentative_size / NDN_ENTRY_AVG_SIZE; ++ /* ++ * So this is like 1048576 / 168, so we get 6241. Now we need to ++ * shift this to get the number of bits. ++ */ ++ size_t shifts = 0; ++ while (possible_elements > 0) { ++ shifts++; ++ possible_elements = possible_elements >> 1; + } ++ /* ++ * So now we can use this to make the slot count. ++ */ ++ t_cache_stats.slots = 1 << shifts; ++ /* Done? */ ++ return; + } + + void + ndn_cache_destroy() + { +- if(!ndn_started){ ++ if (ndn_enabled == 0) { + return; + } +- if(lru_lock){ +- PR_DestroyLock(lru_lock); +- lru_lock = NULL; +- } +- if(ndn_cache_lock){ +- slapi_destroy_rwlock(ndn_cache_lock); +- ndn_cache_lock = NULL; +- } +- if(ndn_cache_hashtable){ +- ndn_cache_free(); +- PL_HashTableDestroy(ndn_cache_hashtable); +- ndn_cache_hashtable = NULL; +- } +- config_set_ndn_cache_enabled(CONFIG_NDN_CACHE, "off", NULL, 1 ); +- slapi_counter_destroy(&ndn_cache->cache_hits); +- slapi_counter_destroy(&ndn_cache->cache_tries); +- slapi_counter_destroy(&ndn_cache->cache_misses); +- slapi_ch_free((void **)&ndn_cache); +- +- ndn_started = 0; ++ slapi_counter_destroy(&(t_cache_stats.cache_tries)); ++ slapi_counter_destroy(&(t_cache_stats.cache_hits)); ++ slapi_counter_destroy(&(t_cache_stats.cache_count)); ++ slapi_counter_destroy(&(t_cache_stats.cache_size)); ++ slapi_counter_destroy(&(t_cache_stats.cache_evicts)); + } + + int + ndn_cache_started() + { +- return ndn_started; ++ return ndn_enabled; + } + + /* + * Look up this dn in the ndn cache + */ + static int +-ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc) ++ndn_cache_lookup(char *dn, size_t dn_len, char **ndn, char **udn, int *rc) + { +- struct ndn_hash_val *ndn_ht_val = NULL; +- char *ndn, *key; +- int rv = 0; +- +- if(NULL == udn){ +- return rv; ++ if (ndn_enabled == 0 || NULL == udn) { ++ return 0; + } + *udn = NULL; +- if(ndn_started == 0){ +- return rv; +- } +- if(dn_len == 0){ +- *result = dn; ++ ++ if (dn_len == 0) { ++ *ndn = dn; + *rc = 0; + return 1; + } +- slapi_counter_increment(ndn_cache->cache_tries); +- slapi_rwlock_rdlock(ndn_cache_lock); +- ndn_ht_val = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn); +- if(ndn_ht_val){ +- ndn_cache_update_lru(&ndn_ht_val->lru_node); +- slapi_counter_increment(ndn_cache->cache_hits); +- if ((ndn_ht_val->len != dn_len) || +- /* even if the lengths match, dn may not be normalized yet. +- * (e.g., 'cn="o=ABC",o=XYZ' vs. 'cn=o\3DABC,o=XYZ') */ +- (memcmp(dn, ndn_ht_val->ndn, dn_len))){ +- *rc = 1; /* free result */ +- ndn = slapi_ch_malloc(ndn_ht_val->len + 1); +- memcpy(ndn, ndn_ht_val->ndn, ndn_ht_val->len); +- ndn[ndn_ht_val->len] = '\0'; +- *result = ndn; +- } else { +- /* the dn was already normalized, just return the dn as the result */ +- *result = dn; +- *rc = 0; +- } +- rv = 1; +- } else { +- /* copy/preserve the udn, so we can use it as the key when we add dn's to the hashtable */ +- key = slapi_ch_malloc(dn_len + 1); +- memcpy(key, dn, dn_len); +- key[dn_len] = '\0'; +- *udn = key; ++ ++ struct ndn_cache *t_cache = pthread_getspecific(ndn_cache_key); ++ if (t_cache == NULL) { ++ t_cache = ndn_thread_cache_create(t_cache_stats.thread_max_size, t_cache_stats.slots); ++ pthread_setspecific(ndn_cache_key, t_cache); ++ /* If we have no cache, we can't look up ... */ ++ return 0; + } +- slapi_rwlock_unlock(ndn_cache_lock); + +- return rv; +-} ++ t_cache->tries++; + +-/* +- * Move this lru node to the top of the list +- */ +-static void +-ndn_cache_update_lru(struct ndn_cache_lru **node) +-{ +- struct ndn_cache_lru *prev, *next, *curr_node = *node; ++ /* ++ * Hash our DN ... ++ */ ++ uint64_t dn_hash = sds_siphash13(dn, dn_len, t_cache->key); ++ /* Where should it be? */ ++ size_t expect_slot = dn_hash % t_cache->slots; + +- if(curr_node == NULL){ +- return; +- } +- PR_Lock(lru_lock); +- if(curr_node->prev == NULL){ +- /* already the top node */ +- PR_Unlock(lru_lock); +- return; +- } +- prev = curr_node->prev; +- next = curr_node->next; +- if(next){ +- next->prev = prev; +- prev->next = next; +- } else { +- /* this was the tail, so reset the tail */ +- ndn_cache->tail = prev; +- prev->next = NULL; ++ /* ++ * Is it there? ++ */ ++ if (t_cache->table[expect_slot] != NULL) { ++ /* ++ * Check it really matches, could be collision. ++ */ ++ struct ndn_cache_value *node = t_cache->table[expect_slot]; ++ while (node != NULL) { ++ if (strcmp(dn, node->dn) == 0) { ++ /* ++ * Update LRU ++ * Are we already the tail? If so, we can just skip. ++ * remember, this means in a set of 1, we will always be tail ++ */ ++ if (t_cache->tail != node) { ++ /* ++ * Okay, we are *not* the tail. We could be anywhere between ++ * tail -> ... -> x -> head ++ * or even, we are the head ourself. ++ */ ++ if (t_cache->head == node) { ++ /* We are the head, update head to our predecessor */ ++ t_cache->head = node->prev; ++ /* Remember, the head has no next. */ ++ t_cache->head->next = NULL; ++ } else { ++ /* Right, we aren't the head, so we have a next node. */ ++ node->next->prev = node->prev; ++ } ++ /* Because we must be in the middle somewhere, we can assume next and prev exist. */ ++ node->prev->next = node->next; ++ /* ++ * Tail can't be NULL if we have a value in the cache, so we can ++ * just deref this. ++ */ ++ node->next = t_cache->tail; ++ t_cache->tail->prev = node; ++ t_cache->tail = node; ++ node->prev = NULL; ++ } ++ /* Update that we have a hit.*/ ++ t_cache->hits++; ++ /* Cope the NDN to the caller. */ ++ *ndn = slapi_ch_strdup(node->ndn); ++ /* Indicate to the caller to free this. */ ++ *rc = 1; ++ ndn_thread_cache_commit_status(t_cache); ++ return 1; ++ } ++ node = node->child; ++ } + } +- curr_node->prev = NULL; +- curr_node->next = ndn_cache->head; +- ndn_cache->head->prev = curr_node; +- ndn_cache->head = curr_node; +- PR_Unlock(lru_lock); ++ /* If we miss, we need to duplicate dn to udn here. */ ++ *udn = slapi_ch_strdup(dn); ++ *rc = 0; ++ ndn_thread_cache_commit_status(t_cache); ++ return 0; + } + + /* +@@ -2936,176 +3233,102 @@ ndn_cache_update_lru(struct ndn_cache_lru **node) + static void + ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len) + { +- struct ndn_hash_val *ht_entry; +- struct ndn_cache_lru *new_node = NULL; +- PLHashEntry *he; +- int size; +- +- if(ndn_started == 0 || dn_len == 0){ ++ if (ndn_enabled == 0) { + return; + } +- if(strlen(ndn) > ndn_len){ ++ if (dn_len == 0) { ++ return; ++ } ++ if (strlen(ndn) > ndn_len) { + /* we need to null terminate the ndn */ + *(ndn + ndn_len) = '\0'; + } + /* + * Calculate the approximate memory footprint of the hash entry, key, and lru entry. + */ +- size = (dn_len * 2) + ndn_len + sizeof(PLHashEntry) + sizeof(struct ndn_hash_val) + sizeof(struct ndn_cache_lru); ++ struct ndn_cache_value *new_value = (struct ndn_cache_value *)slapi_ch_calloc(1, sizeof(struct ndn_cache_value)); ++ new_value->size = sizeof(struct ndn_cache_value) + dn_len + ndn_len; ++ /* DN is alloc for us */ ++ new_value->dn = dn; ++ /* But we need to copy ndn */ ++ new_value->ndn = slapi_ch_strdup(ndn); ++ + /* +- * Create our LRU node ++ * Get our local cache out. + */ +- new_node = (struct ndn_cache_lru *)slapi_ch_malloc(sizeof(struct ndn_cache_lru)); +- if(new_node == NULL){ +- slapi_log_err(SLAPI_LOG_ERR, "ndn_cache_add", "Failed to allocate new lru node.\n"); +- return; ++ struct ndn_cache *t_cache = pthread_getspecific(ndn_cache_key); ++ if (t_cache == NULL) { ++ t_cache = ndn_thread_cache_create(t_cache_stats.thread_max_size, t_cache_stats.slots); ++ pthread_setspecific(ndn_cache_key, t_cache); + } +- new_node->prev = NULL; +- new_node->key = dn; /* dn has already been allocated */ + /* +- * Its possible this dn was added to the hash by another thread. ++ * Hash the DN + */ +- slapi_rwlock_wrlock(ndn_cache_lock); +- ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn); +- if(ht_entry){ +- /* already exists, free the node and return */ +- slapi_rwlock_unlock(ndn_cache_lock); +- slapi_ch_free_string(&new_node->key); +- slapi_ch_free((void **)&new_node); +- return; +- } ++ uint64_t dn_hash = sds_siphash13(new_value->dn, dn_len, t_cache->key); + /* +- * Create the hash entry ++ * Get the insert slot: This works because the number spaces of dn_hash is ++ * a 64bit int, and slots is a power of two. As a result, we end up with ++ * even distribution of the values. + */ +- ht_entry = (struct ndn_hash_val *)slapi_ch_malloc(sizeof(struct ndn_hash_val)); +- if(ht_entry == NULL){ +- slapi_rwlock_unlock(ndn_cache_lock); +- slapi_log_err(SLAPI_LOG_ERR, "ndn_cache_add", "Failed to allocate new hash entry.\n"); +- slapi_ch_free_string(&new_node->key); +- slapi_ch_free((void **)&new_node); +- return; +- } +- ht_entry->ndn = slapi_ch_malloc(ndn_len + 1); +- memcpy(ht_entry->ndn, ndn, ndn_len); +- ht_entry->ndn[ndn_len] = '\0'; +- ht_entry->len = ndn_len; +- ht_entry->size = size; +- ht_entry->lru_node = new_node; ++ size_t insert_slot = dn_hash % t_cache->slots; ++ /* Track this for free */ ++ new_value->slot = insert_slot; ++ + /* +- * Check if our cache is full ++ * Okay, check if we have space, else we need to trim nodes from ++ * the LRU + */ +- PR_Lock(lru_lock); /* grab the lru lock now, as ndn_cache_flush needs it */ +- if(ndn_cache->cache_max_size != 0 && ((ndn_cache->cache_size + size) > ndn_cache->cache_max_size)){ +- ndn_cache_flush(); ++ while (t_cache->head && (t_cache->size + new_value->size) > t_cache->max_size) { ++ struct ndn_cache_value *trim_node = t_cache->head; ++ ndn_thread_cache_value_destroy(t_cache, trim_node); + } ++ + /* +- * Set the ndn cache lru nodes ++ * Add it! + */ +- if(ndn_cache->head == NULL && ndn_cache->tail == NULL){ +- /* this is the first node */ +- ndn_cache->head = new_node; +- ndn_cache->tail = new_node; +- new_node->next = NULL; ++ if (t_cache->table[insert_slot] == NULL) { ++ t_cache->table[insert_slot] = new_value; + } else { +- new_node->next = ndn_cache->head; +- if(ndn_cache->head) +- ndn_cache->head->prev = new_node; ++ /* ++ * Hash collision! We need to replace the bucket then .... ++ * insert at the head of the slot to make this simpler. ++ */ ++ new_value->child = t_cache->table[insert_slot]; ++ t_cache->table[insert_slot] = new_value; + } +- ndn_cache->head = new_node; +- PR_Unlock(lru_lock); ++ + /* +- * Add the new object to the hashtable, and update our stats ++ * Finally, stick this onto the tail because it's the newest. + */ +- he = PL_HashTableAdd(ndn_cache_hashtable, new_node->key, (void *)ht_entry); +- if(he == NULL){ +- slapi_log_err(SLAPI_LOG_ERR, "ndn_cache_add", "Failed to add new entry to hash(%s)\n",dn); +- } else { +- ndn_cache->cache_count++; +- ndn_cache->cache_size += size; ++ if (t_cache->head == NULL) { ++ t_cache->head = new_value; + } +- slapi_rwlock_unlock(ndn_cache_lock); +-} +- +-/* +- * cache is full, remove the least used dn's. lru_lock/ndn_cache write lock are already taken +- */ +-static void +-ndn_cache_flush(void) +-{ +- struct ndn_cache_lru *node, *next, *flush_node; +- int i; +- +- node = ndn_cache->tail; +- for(i = 0; node && i < NDN_FLUSH_COUNT && ndn_cache->cache_count > NDN_MIN_COUNT; i++){ +- flush_node = node; +- /* update the lru */ +- next = node->prev; +- next->next = NULL; +- ndn_cache->tail = next; +- node = next; +- /* now update the hash */ +- ndn_cache->cache_count--; +- ndn_cache_delete(flush_node->key); +- slapi_ch_free_string(&flush_node->key); +- slapi_ch_free((void **)&flush_node); ++ if (t_cache->tail != NULL) { ++ new_value->next = t_cache->tail; ++ t_cache->tail->prev = new_value; + } ++ t_cache->tail = new_value; + +- slapi_log_err(SLAPI_LOG_CACHE, "ndn_cache_flush","Flushed cache.\n"); +-} +- +-static void +-ndn_cache_free(void) +-{ +- struct ndn_cache_lru *node, *next, *flush_node; +- +- if(!ndn_cache){ +- return; +- } +- +- node = ndn_cache->tail; +- while(node && ndn_cache->cache_count){ +- flush_node = node; +- /* update the lru */ +- next = node->prev; +- if(next){ +- next->next = NULL; +- } +- ndn_cache->tail = next; +- node = next; +- /* now update the hash */ +- ndn_cache->cache_count--; +- ndn_cache_delete(flush_node->key); +- slapi_ch_free_string(&flush_node->key); +- slapi_ch_free((void **)&flush_node); +- } +-} +- +-/* this is already "write" locked from ndn_cache_add */ +-static void +-ndn_cache_delete(char *dn) +-{ +- struct ndn_hash_val *ht_entry; ++ /* ++ * And update the stats. ++ */ ++ t_cache->size = t_cache->size + new_value->size; ++ t_cache->count++; + +- ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn); +- if(ht_entry){ +- ndn_cache->cache_size -= ht_entry->size; +- slapi_ch_free_string(&ht_entry->ndn); +- slapi_ch_free((void **)&ht_entry); +- PL_HashTableRemove(ndn_cache_hashtable, dn); +- } + } + + /* stats for monitor */ + void +-ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count) +-{ +- slapi_rwlock_rdlock(ndn_cache_lock); +- *hits = slapi_counter_get_value(ndn_cache->cache_hits); +- *tries = slapi_counter_get_value(ndn_cache->cache_tries); +- *size = ndn_cache->cache_size; +- *max_size = ndn_cache->cache_max_size; +- *count = ndn_cache->cache_count; +- slapi_rwlock_unlock(ndn_cache_lock); ++ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, size_t *thread_size, size_t *evicts, size_t *slots, long *count) ++{ ++ *max_size = t_cache_stats.max_size; ++ *thread_size = t_cache_stats.thread_max_size; ++ *slots = t_cache_stats.slots; ++ *evicts = slapi_counter_get_value(t_cache_stats.cache_evicts); ++ *hits = slapi_counter_get_value(t_cache_stats.cache_hits); ++ *tries = slapi_counter_get_value(t_cache_stats.cache_tries); ++ *size = slapi_counter_get_value(t_cache_stats.cache_size); ++ *count = slapi_counter_get_value(t_cache_stats.cache_count); + } + + /* Common ancestor sdn is allocated. +diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h +index 3910dbe..68b59f3 100644 +--- a/ldap/servers/slapd/slapi-private.h ++++ b/ldap/servers/slapd/slapi-private.h +@@ -380,7 +380,7 @@ char *slapi_dn_normalize_case_original( char *dn ); + void ndn_cache_init(void); + void ndn_cache_destroy(void); + int ndn_cache_started(void); +-void ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count); ++void ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, size_t *thread_size, size_t *evicts, size_t *slots, long *count); + #define NDN_DEFAULT_SIZE 20971520 /* 20mb - size of normalized dn cache */ + + /* filter.c */ +-- +2.9.4 + diff --git a/SOURCES/0062-Ticket-49370-Crash-when-using-a-global-and-local-pw.patch b/SOURCES/0062-Ticket-49370-Crash-when-using-a-global-and-local-pw.patch deleted file mode 100644 index 19077f9..0000000 --- a/SOURCES/0062-Ticket-49370-Crash-when-using-a-global-and-local-pw.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 3bdd7b5cccd2993c5ae5b9d893be15c71373aaf8 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 29 Jan 2018 11:53:33 -0500 -Subject: [PATCH] Ticket 49370 - Crash when using a global and local pw - policies - -Description: This a regression from the previous patch. We were - accidently using a reference to the global pw policy - password storage scheme, which was getting freed after - pblock was done from an operation. The next operation - then used(and double freed) this memory on the next - operation. - -https://pagure.io/389-ds-base/issue/49370 - -Reviewed by: tbordaz (Thanks!) - -(cherry picked from commit d86e0f9634e694feb378ee335d29b2e89fd27e2c) ---- - ldap/servers/slapd/pw.c | 32 +++++++++++++++++--------------- - 1 file changed, 17 insertions(+), 15 deletions(-) - -diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c -index 3a545e12e..451be364d 100644 ---- a/ldap/servers/slapd/pw.c -+++ b/ldap/servers/slapd/pw.c -@@ -209,7 +209,7 @@ pw_name2scheme(char *name) - struct pw_scheme *pwsp; - struct slapdplugin *p; - -- if ((p = plugin_get_pwd_storage_scheme(name, strlen(name), PLUGIN_LIST_PWD_STORAGE_SCHEME)) != NULL) { -+ if (name != NULL && (p = plugin_get_pwd_storage_scheme(name, strlen(name), PLUGIN_LIST_PWD_STORAGE_SCHEME)) != NULL) { - pwsp = (struct pw_scheme *)slapi_ch_malloc(sizeof(struct pw_scheme)); - if (pwsp != NULL) { - typedef int (*CMPFP)(char *, char *); -@@ -1612,18 +1612,18 @@ pw_get_admin_users(passwdPolicy *pwp) - passwdPolicy * - new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - { -+ slapdFrontendConfig_t *slapdFrontendConfig = NULL; - Slapi_ValueSet *values = NULL; -+ Slapi_Value **sval = NULL; - Slapi_Entry *e = NULL, *pw_entry = NULL; -- int type_name_disposition = 0; -+ passwdPolicy *pwdpolicy = NULL; -+ Slapi_Attr *attr = NULL; -+ char *pwscheme_name = NULL; -+ char *attr_name = NULL; - char *actual_type_name = NULL; -+ int type_name_disposition = 0; - int attr_free_flags = 0; - int rc = 0; -- passwdPolicy *pwdpolicy = NULL; -- struct pw_scheme *pwdscheme = NULL; -- Slapi_Attr *attr; -- char *attr_name; -- Slapi_Value **sval; -- slapdFrontendConfig_t *slapdFrontendConfig; - int optype = -1; - - /* If we already allocated a pw policy, return it */ -@@ -1717,9 +1717,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - pw_entry = get_entry(pb, bvp->bv_val); - } - } -- - slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags); -- - slapi_entry_free(e); - - if (pw_entry == NULL) { -@@ -1732,7 +1730,11 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - - /* Set the default values (from libglobs.c) */ - pwpolicy_init_defaults(pwdpolicy); -- pwdpolicy->pw_storagescheme = slapdFrontendConfig->pw_storagescheme; -+ -+ /* Set the current storage scheme */ -+ pwscheme_name = config_get_pw_storagescheme(); -+ pwdpolicy->pw_storagescheme = pw_name2scheme(pwscheme_name); -+ slapi_ch_free_string(&pwscheme_name); - - /* Set the defined values now */ - for (slapi_entry_first_attr(pw_entry, &attr); attr; -@@ -1865,6 +1867,7 @@ new_passwdPolicy(Slapi_PBlock *pb, const char *dn) - } - } else if (!strcasecmp(attr_name, "passwordstoragescheme")) { - if ((sval = attr_get_present_values(attr))) { -+ free_pw_scheme(pwdpolicy->pw_storagescheme); - pwdpolicy->pw_storagescheme = - pw_name2scheme((char *)slapi_value_get_string(*sval)); - } -@@ -1924,10 +1927,9 @@ done: - * structure from slapdFrontendconfig - */ - *pwdpolicy = slapdFrontendConfig->pw_policy; -- pwdscheme = (struct pw_scheme *)slapi_ch_calloc(1, sizeof(struct pw_scheme)); -- *pwdscheme = *slapdFrontendConfig->pw_storagescheme; -- pwdscheme->pws_name = strdup(slapdFrontendConfig->pw_storagescheme->pws_name); -- pwdpolicy->pw_storagescheme = pwdscheme; -+ pwscheme_name = config_get_pw_storagescheme(); -+ pwdpolicy->pw_storagescheme = pw_name2scheme(pwscheme_name); -+ slapi_ch_free_string(&pwscheme_name); - pwdpolicy->pw_admin = slapi_sdn_dup(slapdFrontendConfig->pw_policy.pw_admin); - pw_get_admin_users(pwdpolicy); - if (pb) { --- -2.13.6 - diff --git a/SOURCES/0063-Ticket-49330-Add-endian-header-file-check-to-configu.patch b/SOURCES/0063-Ticket-49330-Add-endian-header-file-check-to-configu.patch new file mode 100644 index 0000000..f1dce6f --- /dev/null +++ b/SOURCES/0063-Ticket-49330-Add-endian-header-file-check-to-configu.patch @@ -0,0 +1,25 @@ +From c9817ebe42a97ac7df155582957927b4d1d08c5f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0063-Ticket-49557-Add-config-option-for-checking-CRL-on-o.patch b/SOURCES/0063-Ticket-49557-Add-config-option-for-checking-CRL-on-o.patch deleted file mode 100644 index b79ed65..0000000 --- a/SOURCES/0063-Ticket-49557-Add-config-option-for-checking-CRL-on-o.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 656b141630c5f37a953a75ff05d3a1a30b14eef1 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 1 Feb 2018 14:28:24 -0500 -Subject: [PATCH] Ticket 49557 - Add config option for checking CRL on outbound - SSL Connections - -Bug Description: There are cases where a CRL is not available during an outbound - replication connection. This is seen as an error by openldap, - and the connection fails. - -Fix Description: Add on/off option for checking the CRL. The default is not to - check the CRL. - -https://pagure.io/389-ds-base/issue/49557 - -Reviewed by: wibrown, Ludwig Krispenz, Thierry Bordaz ---- - dirsrvtests/tests/suites/{ssl => tls}/__init__.py | 0 - dirsrvtests/tests/suites/tls/tls_check_crl_test.py | 52 +++++++++++++++++ - ldap/schema/01core389.ldif | 1 + - ldap/servers/slapd/ldaputil.c | 9 ++- - ldap/servers/slapd/libglobs.c | 66 +++++++++++++++++++++- - ldap/servers/slapd/proto-slap.h | 2 + - ldap/servers/slapd/slap.h | 10 +++- - 7 files changed, 135 insertions(+), 5 deletions(-) - rename dirsrvtests/tests/suites/{ssl => tls}/__init__.py (100%) - create mode 100644 dirsrvtests/tests/suites/tls/tls_check_crl_test.py - -diff --git a/dirsrvtests/tests/suites/ssl/__init__.py b/dirsrvtests/tests/suites/tls/__init__.py -similarity index 100% -rename from dirsrvtests/tests/suites/ssl/__init__.py -rename to dirsrvtests/tests/suites/tls/__init__.py -diff --git a/dirsrvtests/tests/suites/tls/tls_check_crl_test.py b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py -new file mode 100644 -index 000000000..8b4d07f94 ---- /dev/null -+++ b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py -@@ -0,0 +1,52 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2018 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+ -+ -+import pytest -+import ldap -+from lib389.topologies import topology_st -+ -+def test_tls_check_crl(topology_st): -+ """Test that TLS check_crl configurations work as expected. -+ -+ :id: -+ :steps: -+ 1. Enable TLS -+ 2. Set invalid value -+ 3. Set valid values -+ 4. Check config reset -+ :expectedresults: -+ 1. TlS is setup -+ 2. The invalid value is rejected -+ 3. The valid values are used -+ 4. The value can be reset -+ """ -+ standalone = topology_st.standalone -+ # Enable TLS -+ standalone.enable_tls() -+ # Check all the valid values. -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') -+ with pytest.raises(ldap.OPERATIONS_ERROR): -+ standalone.config.set('nsslapd-tls-check-crl', 'tnhoeutnoeutn') -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') -+ -+ standalone.config.set('nsslapd-tls-check-crl', 'peer') -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'peer') -+ -+ standalone.config.set('nsslapd-tls-check-crl', 'none') -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') -+ -+ standalone.config.set('nsslapd-tls-check-crl', 'all') -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'all') -+ -+ standalone.config.remove_all('nsslapd-tls-check-crl') -+ assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') -+ -+ -+ -diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif -index ab124c86c..c7f9fef2b 100644 ---- a/ldap/schema/01core389.ldif -+++ b/ldap/schema/01core389.ldif -@@ -304,6 +304,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2332 NAME 'allowWeakDHParam' DESC 'Netsc - attributeTypes: ( 2.16.840.1.113730.3.1.2333 NAME 'nsds5ReplicaReleaseTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2335 NAME 'nsds5ReplicaIgnoreMissingChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) - attributeTypes: ( 2.16.840.1.113730.3.1.2336 NAME 'nsDS5ReplicaBindDnGroupCheckInterval' DESC 'Replication configuration setting for controlling the bind dn group check interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) -+attributeTypes: ( 2.16.840.1.113730.3.1.2344 NAME 'nsslapd-tls-check-crl' DESC 'Check CRL when opening outbound TLS connections. Valid options are none, peer, all.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' ) - # - # objectclasses - # -diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c -index fa9d276a3..2fc2f0615 100644 ---- a/ldap/servers/slapd/ldaputil.c -+++ b/ldap/servers/slapd/ldaputil.c -@@ -570,6 +570,7 @@ slapi_ldif_parse_line( - } - - #if defined(USE_OPENLDAP) -+ - static int - setup_ol_tls_conn(LDAP *ld, int clientauth) - { -@@ -602,7 +603,13 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) - } - } - if (slapi_client_uses_openssl(ld)) { -- const int crlcheck = LDAP_OPT_X_TLS_CRL_ALL; -+ int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE; -+ tls_check_crl_t tls_check_state = config_get_tls_check_crl(); -+ if (tls_check_state == TLS_CHECK_PEER) { -+ crlcheck = LDAP_OPT_X_TLS_CRL_PEER; -+ } else if (tls_check_state == TLS_CHECK_ALL) { -+ crlcheck = LDAP_OPT_X_TLS_CRL_ALL; -+ } - /* Sets the CRL evaluation strategy. */ - rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck); - if (rc) { -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index c1a765aca..eb6552af1 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -157,7 +157,8 @@ typedef enum { - CONFIG_STRING_OR_EMPTY, /* use an empty string */ - CONFIG_SPECIAL_ANON_ACCESS_SWITCH, /* maps strings to an enumeration */ - CONFIG_SPECIAL_VALIDATE_CERT_SWITCH, /* maps strings to an enumeration */ -- CONFIG_SPECIAL_UNHASHED_PW_SWITCH /* unhashed pw: on/off/nolog */ -+ CONFIG_SPECIAL_UNHASHED_PW_SWITCH, /* unhashed pw: on/off/nolog */ -+ CONFIG_SPECIAL_TLS_CHECK_CRL, /* maps enum tls_check_crl_t to char * */ - } ConfigVarType; - - static int32_t config_set_onoff(const char *attrname, char *value, int32_t *configvalue, char *errorbuf, int apply); -@@ -1173,7 +1174,15 @@ static struct config_get_and_set - {CONFIG_LOGGING_BACKEND, NULL, - log_set_backend, 0, - (void **)&global_slapdFrontendConfig.logging_backend, -- CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL}}; -+ CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL}, -+ {CONFIG_TLS_CHECK_CRL_ATTRIBUTE, config_set_tls_check_crl, -+ NULL, 0, -+ (void **)&global_slapdFrontendConfig.tls_check_crl, -+ CONFIG_SPECIAL_TLS_CHECK_CRL, (ConfigGetFunc)config_get_tls_check_crl, -+ "none" /* Allow reset to this value */} -+ -+ /* End config */ -+ }; - - /* - * hashNocaseString - used for case insensitive hash lookups -@@ -1506,7 +1515,6 @@ FrontendConfig_init(void) - cfg->maxdescriptors = SLAPD_DEFAULT_MAXDESCRIPTORS; - cfg->groupevalnestlevel = SLAPD_DEFAULT_GROUPEVALNESTLEVEL; - cfg->snmp_index = SLAPD_DEFAULT_SNMP_INDEX; -- - cfg->SSLclientAuth = SLAPD_DEFAULT_SSLCLIENTAUTH; - - #ifdef USE_SYSCONF -@@ -1524,6 +1532,7 @@ FrontendConfig_init(void) - #endif - init_security = cfg->security = LDAP_OFF; - init_ssl_check_hostname = cfg->ssl_check_hostname = LDAP_ON; -+ cfg->tls_check_crl = TLS_CHECK_NONE; - init_return_exact_case = cfg->return_exact_case = LDAP_ON; - init_result_tweak = cfg->result_tweak = LDAP_OFF; - init_attrname_exceptions = cfg->attrname_exceptions = LDAP_OFF; -@@ -2042,6 +2051,7 @@ config_set_port(const char *attrname, char *port, char *errorbuf, int apply) - return retVal; - } - -+ - int - config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply) - { -@@ -2073,6 +2083,33 @@ config_set_secureport(const char *attrname, char *port, char *errorbuf, int appl - } - - -+int32_t -+config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply) -+{ -+ int32_t retVal = LDAP_SUCCESS; -+ /* Default */ -+ tls_check_crl_t state = TLS_CHECK_NONE; -+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -+ -+ if (strcasecmp(value, "none") == 0) { -+ state = TLS_CHECK_NONE; -+ } else if (strcasecmp(value, "peer") == 0) { -+ state = TLS_CHECK_PEER; -+ } else if (strcasecmp(value, "all") == 0) { -+ state = TLS_CHECK_ALL; -+ } else { -+ retVal = LDAP_OPERATIONS_ERROR; -+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: unsupported value: %s", attrname, value); -+ } -+ -+ if (retVal == LDAP_SUCCESS && apply) { -+ slapi_atomic_store_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), state, __ATOMIC_RELEASE); -+ } -+ -+ return retVal; -+} -+ -+ - int - config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply) - { -@@ -4591,6 +4628,12 @@ config_set_versionstring(const char *attrname __attribute__((unused)), char *ver - - #define config_copy_strval(s) s ? slapi_ch_strdup(s) : NULL; - -+tls_check_crl_t -+config_get_tls_check_crl() { -+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); -+ return (tls_check_crl_t)slapi_atomic_load_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), __ATOMIC_ACQUIRE); -+} -+ - int - config_get_port() - { -@@ -7439,6 +7482,23 @@ config_set_value( - slapi_entry_attr_set_int(e, cgas->attr_name, ival); - break; - -+ case CONFIG_SPECIAL_TLS_CHECK_CRL: -+ if (!value) { -+ slapi_entry_attr_set_charptr(e, cgas->attr_name, (char *)cgas->initvalue); -+ break; -+ } -+ tls_check_crl_t state = *(tls_check_crl_t *)value; -+ -+ if (state == TLS_CHECK_ALL) { -+ sval = "all"; -+ } else if (state == TLS_CHECK_PEER) { -+ sval = "peer"; -+ } else { -+ sval = "none"; -+ } -+ slapi_entry_attr_set_charptr(e, cgas->attr_name, sval); -+ break; -+ - case CONFIG_SPECIAL_SSLCLIENTAUTH: - if (!value) { - slapi_entry_attr_set_charptr(e, cgas->attr_name, "off"); -diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h -index 3b7ab53b2..b13334ad1 100644 ---- a/ldap/servers/slapd/proto-slap.h -+++ b/ldap/servers/slapd/proto-slap.h -@@ -236,6 +236,7 @@ int config_set_port(const char *attrname, char *port, char *errorbuf, int apply) - int config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply); - int config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply); - int config_set_ssl_check_hostname(const char *attrname, char *value, char *errorbuf, int apply); -+int32_t config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply); - int config_set_SSL3ciphers(const char *attrname, char *value, char *errorbuf, int apply); - int config_set_localhost(const char *attrname, char *value, char *errorbuf, int apply); - int config_set_listenhost(const char *attrname, char *value, char *errorbuf, int apply); -@@ -397,6 +398,7 @@ void log_disable_hr_timestamps(void); - - int config_get_SSLclientAuth(void); - int config_get_ssl_check_hostname(void); -+tls_check_crl_t config_get_tls_check_crl(void); - char *config_get_SSL3ciphers(void); - char *config_get_localhost(void); - char *config_get_listenhost(void); -diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h -index 216d94afd..443d90094 100644 ---- a/ldap/servers/slapd/slap.h -+++ b/ldap/servers/slapd/slap.h -@@ -443,6 +443,13 @@ typedef void (*VFPV)(); /* takes undefined arguments */ - typedef int32_t slapi_onoff_t; - typedef int32_t slapi_int_t; - -+typedef enum _tls_check_crl_t { -+ TLS_CHECK_NONE = 0, -+ TLS_CHECK_PEER = 1, -+ TLS_CHECK_ALL = 2, -+} tls_check_crl_t; -+ -+ - struct subfilt - { - char *sf_type; -@@ -2151,6 +2158,7 @@ typedef struct _slapdEntryPoints - #define CONFIG_RUNDIR_ATTRIBUTE "nsslapd-rundir" - #define CONFIG_SSLCLIENTAUTH_ATTRIBUTE "nsslapd-SSLclientAuth" - #define CONFIG_SSL_CHECK_HOSTNAME_ATTRIBUTE "nsslapd-ssl-check-hostname" -+#define CONFIG_TLS_CHECK_CRL_ATTRIBUTE "nsslapd-tls-check-crl" - #define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters" - #define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout" - #define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external" -@@ -2263,6 +2271,7 @@ typedef struct _slapdFrontendConfig - slapi_onoff_t security; - int SSLclientAuth; - slapi_onoff_t ssl_check_hostname; -+ tls_check_crl_t tls_check_crl; - int validate_cert; - int sizelimit; - int SNMPenabled; -@@ -2294,7 +2303,6 @@ typedef struct _slapdFrontendConfig - slapi_onoff_t plugin_track; - slapi_onoff_t moddn_aci; - struct pw_scheme *pw_storagescheme; -- - slapi_onoff_t pwpolicy_local; - slapi_onoff_t pw_is_global_policy; - slapi_onoff_t pwpolicy_inherit_global; --- -2.13.6 - diff --git a/SOURCES/0064-Ticket-49257-only-register-modify-callbacks.patch b/SOURCES/0064-Ticket-49257-only-register-modify-callbacks.patch new file mode 100644 index 0000000..5391136 --- /dev/null +++ b/SOURCES/0064-Ticket-49257-only-register-modify-callbacks.patch @@ -0,0 +1,87 @@ +From bbe3403a88f9adecbd5d4187ceeb080fb51d9d14 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0064-Ticket-49560-nsslapd-extract-pemfiles-should-be-enab.patch b/SOURCES/0064-Ticket-49560-nsslapd-extract-pemfiles-should-be-enab.patch deleted file mode 100644 index d4eeeeb..0000000 --- a/SOURCES/0064-Ticket-49560-nsslapd-extract-pemfiles-should-be-enab.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 10ec64288dcc25fd855bc05601bc4794ecea2003 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 6 Feb 2018 19:49:22 +0100 -Subject: [PATCH] Ticket 49560 - nsslapd-extract-pemfiles should be enabled by - default as openldap is moving to openssl - -Bug Description: - Due to a change in the OpenLDAP client libraries (switching from NSS to OpenSSL), - the TLS options LDAP_OPT_X_TLS_CACERTFILE, LDAP_OPT_X_TLS_KEYFILE, LDAP_OPT_X_TLS_CERTFILE, - need to specify path to PEM files. - - Those PEM files are extracted from the key/certs from the NSS db in /etc/dirsrv/slapd-xxx - - Those files are extracted if the option (under 'cn=config') nsslapd-extract-pemfiles is set to 'on'. - - The default value is 'off', that prevent secure outgoing connection. - -Fix Description: - - Enable nsslapd-extract-pemfiles by default - Then when establishing an outgoing connection, if it is not using NSS crypto layer - and the pem files have been extracted then use the PEM files - -https://pagure.io/389-ds-base/issue/49560 - -Reviewed by: mreynolds & mhonek - -Platforms tested: RHEL 7.5 - -Flag Day: no - -Doc impact: no - -Signed-off-by: Mark Reynolds -(cherry picked from commit 8304caec593b591558c9c18de9bcb6b2f23db5b6) ---- - ldap/servers/slapd/ldaputil.c | 32 ++++++++++++++++---------------- - ldap/servers/slapd/libglobs.c | 2 +- - ldap/servers/slapd/ssl.c | 2 +- - 3 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c -index 2fc2f0615..fcf22e632 100644 ---- a/ldap/servers/slapd/ldaputil.c -+++ b/ldap/servers/slapd/ldaputil.c -@@ -591,7 +591,7 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) - slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn", - "failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength); - } -- if (slapi_client_uses_non_nss(ld)) { -+ if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) { - cacert = slapi_get_cacertfile(); - if (cacert) { - /* CA Cert PEM file exists. Set the path to openldap option. */ -@@ -602,21 +602,21 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) - cacert, rc, ldap_err2string(rc)); - } - } -- if (slapi_client_uses_openssl(ld)) { -- int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE; -- tls_check_crl_t tls_check_state = config_get_tls_check_crl(); -- if (tls_check_state == TLS_CHECK_PEER) { -- crlcheck = LDAP_OPT_X_TLS_CRL_PEER; -- } else if (tls_check_state == TLS_CHECK_ALL) { -- crlcheck = LDAP_OPT_X_TLS_CRL_ALL; -- } -- /* Sets the CRL evaluation strategy. */ -- rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck); -- if (rc) { -- slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn", -- "Could not set CRLCHECK [%d]: %d:%s\n", -- crlcheck, rc, ldap_err2string(rc)); -- } -+ } -+ if (slapi_client_uses_openssl(ld)) { -+ int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE; -+ tls_check_crl_t tls_check_state = config_get_tls_check_crl(); -+ if (tls_check_state == TLS_CHECK_PEER) { -+ crlcheck = LDAP_OPT_X_TLS_CRL_PEER; -+ } else if (tls_check_state == TLS_CHECK_ALL) { -+ crlcheck = LDAP_OPT_X_TLS_CRL_ALL; -+ } -+ /* Sets the CRL evaluation strategy. */ -+ rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck); -+ if (rc) { -+ slapi_log_err(SLAPI_LOG_ERR, "setup_ol_tls_conn", -+ "Could not set CRLCHECK [%d]: %d:%s\n", -+ crlcheck, rc, ldap_err2string(rc)); - } - } - /* tell it where our cert db/file is */ -diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c -index eb6552af1..3bd5c1826 100644 ---- a/ldap/servers/slapd/libglobs.c -+++ b/ldap/servers/slapd/libglobs.c -@@ -1688,7 +1688,7 @@ FrontendConfig_init(void) - init_malloc_mmap_threshold = cfg->malloc_mmap_threshold = DEFAULT_MALLOC_UNSET; - #endif - -- init_extract_pem = cfg->extract_pem = LDAP_OFF; -+ init_extract_pem = cfg->extract_pem = LDAP_ON; - - /* Done, unlock! */ - CFG_UNLOCK_WRITE(cfg); -diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c -index 52ac7ea9f..36b09fd16 100644 ---- a/ldap/servers/slapd/ssl.c -+++ b/ldap/servers/slapd/ssl.c -@@ -2462,7 +2462,7 @@ slapd_SSL_client_auth(LDAP *ld) - errorCode, slapd_pr_strerror(errorCode)); - } else { - #if defined(USE_OPENLDAP) -- if (slapi_client_uses_non_nss(ld)) { -+ if (slapi_client_uses_non_nss(ld) && config_get_extract_pem()) { - char *certdir = config_get_certdir(); - char *keyfile = NULL; - char *certfile = NULL; --- -2.13.6 - diff --git a/SOURCES/0065-Ticket-49291-slapi_search_internal_callback_pb-may-S.patch b/SOURCES/0065-Ticket-49291-slapi_search_internal_callback_pb-may-S.patch new file mode 100644 index 0000000..219ba58 --- /dev/null +++ b/SOURCES/0065-Ticket-49291-slapi_search_internal_callback_pb-may-S.patch @@ -0,0 +1,46 @@ +From 28529671057c95327a35c326ee99fcafccad9de9 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +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 + diff --git a/SOURCES/0065-Ticket-bz1525628-invalid-password-migration-causes-u.patch b/SOURCES/0065-Ticket-bz1525628-invalid-password-migration-causes-u.patch deleted file mode 100644 index 981ce22..0000000 --- a/SOURCES/0065-Ticket-bz1525628-invalid-password-migration-causes-u.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 40fcaabfaa2c865471cc5fb1fab04106bc3ec611 Mon Sep 17 00:00:00 2001 -From: William Brown -Date: Thu, 18 Jan 2018 11:27:58 +1000 -Subject: [PATCH] Ticket bz1525628 - invalid password migration causes unauth - bind - -Bug Description: Slapi_ct_memcmp expects both inputs to be -at LEAST size n. If they are not, we only compared UP to n. - -Invalid migrations of passwords (IE {CRYPT}XX) would create -a pw which is just salt and no hash. ct_memcmp would then -only verify the salt bits and would allow the authentication. - -This relies on an administrative mistake both of allowing -password migration (nsslapd-allow-hashed-passwords) and then -subsequently migrating an INVALID password to the server. - -Fix Description: slapi_ct_memcmp now access n1, n2 size -and will FAIL if they are not the same, but will still compare -n bytes, where n is the "longest" memory, to the first byte -of the other to prevent length disclosure of the shorter -value (generally the mis-migrated password) - -https://bugzilla.redhat.com/show_bug.cgi?id=1525628 - -Author: wibrown - -Review by: ??? - -Signed-off-by: Mark Reynolds ---- - .../bz1525628_ct_memcmp_invalid_hash_test.py | 56 ++++++++++++++++++++++ - ldap/servers/plugins/pwdstorage/clear_pwd.c | 4 +- - ldap/servers/plugins/pwdstorage/crypt_pwd.c | 4 +- - ldap/servers/plugins/pwdstorage/md5_pwd.c | 4 +- - ldap/servers/plugins/pwdstorage/sha_pwd.c | 16 +++++-- - ldap/servers/plugins/pwdstorage/smd5_pwd.c | 2 +- - ldap/servers/slapd/ch_malloc.c | 36 ++++++++++++-- - ldap/servers/slapd/slapi-plugin.h | 2 +- - 8 files changed, 108 insertions(+), 16 deletions(-) - create mode 100644 dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py - -diff --git a/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py -new file mode 100644 -index 000000000..2f38384a1 ---- /dev/null -+++ b/dirsrvtests/tests/suites/password/bz1525628_ct_memcmp_invalid_hash_test.py -@@ -0,0 +1,56 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2018 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+ -+import ldap -+import pytest -+import logging -+from lib389.topologies import topology_st -+from lib389._constants import PASSWORD, DEFAULT_SUFFIX -+ -+from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES -+ -+logging.getLogger(__name__).setLevel(logging.DEBUG) -+log = logging.getLogger(__name__) -+ -+def test_invalid_hash_fails(topology_st): -+ """When given a malformed hash from userpassword migration -+ slapi_ct_memcmp would check only to the length of the shorter -+ field. This affects some values where it would ONLY verify -+ the salt is valid, and thus would allow any password to bind. -+ -+ :id: 8131c029-7147-47db-8d03-ec5db2a01cfb -+ :setup: Standalone Instance -+ :steps: -+ 1. Create a user -+ 2. Add an invalid password hash (truncated) -+ 3. Attempt to bind -+ :expectedresults: -+ 1. User is added -+ 2. Invalid pw hash is added -+ 3. Bind fails -+ """ -+ log.info("Running invalid hash test") -+ -+ # Allow setting raw password hashes for migration. -+ topology_st.standalone.config.set('nsslapd-allow-hashed-passwords', 'on') -+ -+ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) -+ user = users.create(properties=TEST_USER_PROPERTIES) -+ user.set('userPassword', '{CRYPT}XX') -+ -+ # Attempt to bind. This should fail. -+ with pytest.raises(ldap.INVALID_CREDENTIALS): -+ user.bind(PASSWORD) -+ with pytest.raises(ldap.INVALID_CREDENTIALS): -+ user.bind('XX') -+ with pytest.raises(ldap.INVALID_CREDENTIALS): -+ user.bind('{CRYPT}XX') -+ -+ log.info("PASSED") -+ -diff --git a/ldap/servers/plugins/pwdstorage/clear_pwd.c b/ldap/servers/plugins/pwdstorage/clear_pwd.c -index f5e6f9d4c..3d340752d 100644 ---- a/ldap/servers/plugins/pwdstorage/clear_pwd.c -+++ b/ldap/servers/plugins/pwdstorage/clear_pwd.c -@@ -39,7 +39,7 @@ clear_pw_cmp(const char *userpwd, const char *dbpwd) - * However, even if the first part of userpw matches dbpwd, but len !=, we - * have already failed anyawy. This prevents substring matching. - */ -- if (slapi_ct_memcmp(userpwd, dbpwd, len_dbp) != 0) { -+ if (slapi_ct_memcmp(userpwd, dbpwd, len_user, len_dbp) != 0) { - result = 1; - } - } else { -@@ -51,7 +51,7 @@ clear_pw_cmp(const char *userpwd, const char *dbpwd) - * dbpwd to itself. We have already got result == 1 if we are here, so we are - * just trying to take up time! - */ -- if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp)) { -+ if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp, len_dbp)) { - /* Do nothing, we have the if to fix a coverity check. */ - } - } -diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c -index 3bd226581..0dccd1b51 100644 ---- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c -+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c -@@ -65,13 +65,13 @@ crypt_close(Slapi_PBlock *pb __attribute__((unused))) - int - crypt_pw_cmp(const char *userpwd, const char *dbpwd) - { -- int rc; -+ int32_t rc; - char *cp; - PR_Lock(cryptlock); - /* we use salt (first 2 chars) of encoded password in call to crypt() */ - cp = crypt(userpwd, dbpwd); - if (cp) { -- rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd)); -+ rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd), strlen(cp)); - } else { - rc = -1; - } -diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c -index 1e2cf58e7..2c2aacaa6 100644 ---- a/ldap/servers/plugins/pwdstorage/md5_pwd.c -+++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c -@@ -30,7 +30,7 @@ - int - md5_pw_cmp(const char *userpwd, const char *dbpwd) - { -- int rc = -1; -+ int32_t rc = -1; - char *bver; - PK11Context *ctx = NULL; - unsigned int outLen; -@@ -57,7 +57,7 @@ md5_pw_cmp(const char *userpwd, const char *dbpwd) - bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item); - /* bver points to b2a_out upon success */ - if (bver) { -- rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd)); -+ rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd), strlen(bver)); - } else { - slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME, - "Could not base64 encode hashed value for password compare"); -diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c -index 1fbe0bc82..381b31d7c 100644 ---- a/ldap/servers/plugins/pwdstorage/sha_pwd.c -+++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c -@@ -49,7 +49,7 @@ sha_pw_cmp(const char *userpwd, const char *dbpwd, unsigned int shaLen) - char userhash[MAX_SHA_HASH_SIZE]; - char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3]; - char *dbhash = quick_dbhash; -- struct berval salt; -+ struct berval salt = {0}; - PRUint32 hash_len; - unsigned int secOID; - char *schemeName; -@@ -122,9 +122,19 @@ sha_pw_cmp(const char *userpwd, const char *dbpwd, unsigned int shaLen) - - /* the proof is in the comparison... */ - if (hash_len >= shaLen) { -- result = slapi_ct_memcmp(userhash, dbhash, shaLen); -+ /* -+ * This say "if the hash has a salt IE >, OR if they are equal, check the hash component ONLY. -+ * This is why we repeat shaLen twice, even though it seems odd. If you have a dbhast of ssha -+ * it's len is 28, and the userpw is 20, but 0 - 20 is the sha, and 21-28 is the salt, which -+ * has already been processed into userhash. -+ * The case where dbpwd is truncated is handled above in "invalid base64" arm. -+ */ -+ result = slapi_ct_memcmp(userhash, dbhash, shaLen, shaLen); - } else { -- result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, hash_len - OLD_SALT_LENGTH); -+ /* This case is for if the salt is at the START, which only applies to DS40B1 case. -+ * May never be a valid check... -+ */ -+ result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, shaLen, hash_len - OLD_SALT_LENGTH); - } - - loser: -diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c -index a83ac6fa4..cbfc74ff3 100644 ---- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c -+++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c -@@ -82,7 +82,7 @@ smd5_pw_cmp(const char *userpwd, const char *dbpwd) - PK11_DestroyContext(ctx, 1); - - /* Compare everything up to the salt. */ -- rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH); -+ rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH, MD5_LENGTH); - - loser: - if (dbhash && dbhash != quick_dbhash) -diff --git a/ldap/servers/slapd/ch_malloc.c b/ldap/servers/slapd/ch_malloc.c -index ef436b3e8..90a2b2c1a 100644 ---- a/ldap/servers/slapd/ch_malloc.c -+++ b/ldap/servers/slapd/ch_malloc.c -@@ -336,8 +336,8 @@ slapi_ch_smprintf(const char *fmt, ...) - - /* Constant time memcmp. Does not shortcircuit on failure! */ - /* This relies on p1 and p2 both being size at least n! */ --int --slapi_ct_memcmp(const void *p1, const void *p2, size_t n) -+int32_t -+slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2) - { - int result = 0; - const unsigned char *_p1 = (const unsigned char *)p1; -@@ -347,9 +347,35 @@ slapi_ct_memcmp(const void *p1, const void *p2, size_t n) - return 2; - } - -- for (size_t i = 0; i < n; i++) { -- if (_p1[i] ^ _p2[i]) { -- result = 1; -+ if (n1 == n2) { -+ for (size_t i = 0; i < n1; i++) { -+ if (_p1[i] ^ _p2[i]) { -+ result = 1; -+ } -+ } -+ } else { -+ const unsigned char *_pa; -+ const unsigned char *_pb; -+ size_t nl; -+ if (n2 > n1) { -+ _pa = _p2; -+ _pb = _p2; -+ nl = n2; -+ } else { -+ _pa = _p1; -+ _pb = _p1; -+ nl = n1; -+ } -+ /* We already fail as n1 != n2 */ -+ result = 3; -+ for (size_t i = 0; i < nl; i++) { -+ if (_pa[i] ^ _pb[i]) { -+ /* -+ * If we don't mutate result here, dead code elimination -+ * we remove for loop. -+ */ -+ result = 4; -+ } - } - } - return result; -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index 4566202d3..95cdcc0da 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -5862,7 +5862,7 @@ char *slapi_ch_smprintf(const char *fmt, ...) - * \param n length in bytes of the content of p1 AND p2. - * \return 0 on match. 1 on non-match. 2 on presence of NULL pointer in p1 or p2. - */ --int slapi_ct_memcmp(const void *p1, const void *p2, size_t n); -+int32_t slapi_ct_memcmp(const void *p1, const void *p2, size_t n1, size_t n2); - - /* - * syntax plugin routines --- -2.13.6 - diff --git a/SOURCES/0066-Ticket-49370-local-password-policies-should-use-the-.patch b/SOURCES/0066-Ticket-49370-local-password-policies-should-use-the-.patch new file mode 100644 index 0000000..2753f3b --- /dev/null +++ b/SOURCES/0066-Ticket-49370-local-password-policies-should-use-the-.patch @@ -0,0 +1,51 @@ +From 1ec56936d29985a55f9529c1ea3e71056557b3ff Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0066-Ticket-49545-final-substring-extended-filter-search-.patch b/SOURCES/0066-Ticket-49545-final-substring-extended-filter-search-.patch deleted file mode 100644 index 6aea31b..0000000 --- a/SOURCES/0066-Ticket-49545-final-substring-extended-filter-search-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 183517787fe86c1bc2359ad807318b8bca573d17 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Fri, 19 Jan 2018 16:34:36 +0100 -Subject: [PATCH] Ticket 49545 - final substring extended filter search returns - invalid result - -Bug Description: - During a search (using extended filter with final substring), the server - checks the filter before returning the matching entries. - When checking the attribute value against the filter, it - uses the wrong value. - -Fix Description: - Make suree it uses the right portion of the attribute value, in order - to generate the keys to compare. - -https://pagure.io/389-ds-base/issue/49545 - -Reviewed by: Ludwig Krispenz - -Platforms tested: F26 - -Flag Day: no - -Doc impact: no - -Signed-off-by: Mark Reynolds ---- - ldap/servers/plugins/collation/orfilter.c | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c -index a98d90219..672ee7b19 100644 ---- a/ldap/servers/plugins/collation/orfilter.c -+++ b/ldap/servers/plugins/collation/orfilter.c -@@ -182,17 +182,33 @@ ss_filter_match(or_filter_t * or, struct berval **vals) - } else { /* final */ - auto size_t attempts = MAX_CHAR_COMBINING; - auto char *limit = v.bv_val; -+ auto char *end; - auto struct berval **vkeys; - auto struct berval *vals[2]; - auto struct berval key; -+ - rc = -1; - vals[0] = &v; - vals[1] = NULL; - key.bv_val = (*k)->bv_val; - key.bv_len = (*k)->bv_len - 1; -- v.bv_val = (*vals)->bv_val + (*vals)->bv_len; -+ /* In the following lines it will loop to find -+ * if the end of the attribute value matches the 'final' of the filter -+ * Short summary: -+ * vals contains the attribute value :for example "hello world" -+ * key contain the key generated from the indexing of final part of the filter. -+ * for example filter=(=*ld), so key contains the indexing("ld"). -+ * -+ * The loop will iterate over the attribute value (vals) from the end of string -+ * to the begining. So it will try to index('d'), index('ld'), index('rld'), index('orld')... -+ * -+ * At each iteration if the key generated from indexing the portion of vals, matches -+ * the key generate from the final part of the filter, then the loop stops => we are done -+ */ -+ end = v.bv_val + v.bv_len - 1; -+ v.bv_val = end; - while (1) { -- v.bv_len = (*vals)->bv_len - (v.bv_val - (*vals)->bv_val); -+ v.bv_len = end - v.bv_val + 1; - vkeys = ix->ix_index(ix, vals, NULL); - if (vkeys && vkeys[0]) { - auto const struct berval *vkey = vkeys[0]; --- -2.13.6 - diff --git a/SOURCES/0067-Ticket-49380-Crash-when-adding-invalid-replication.patch b/SOURCES/0067-Ticket-49380-Crash-when-adding-invalid-replication.patch new file mode 100644 index 0000000..cb988c3 --- /dev/null +++ b/SOURCES/0067-Ticket-49380-Crash-when-adding-invalid-replication.patch @@ -0,0 +1,55 @@ +From af59afa03296160577e419257772d5319796a992 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0067-Ticket-49551-v3-correct-handling-of-numsubordinates-.patch b/SOURCES/0067-Ticket-49551-v3-correct-handling-of-numsubordinates-.patch deleted file mode 100644 index 8c41a91..0000000 --- a/SOURCES/0067-Ticket-49551-v3-correct-handling-of-numsubordinates-.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 233b64f26df76aa50f4b37aaf6b3804d208fdc1b Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Mon, 12 Feb 2018 09:24:25 +0100 -Subject: [PATCH] Ticket 49551 - v3 - correct handling of numsubordinates for - cenotaphs and tombstone delete - - Bug: The ticket exposed several problems with tombstone handling. - - tombstone entries of conflicts were not purged in tombstone purging - - cenotaphs are tombstone, but the subordinate count was not managed properly - - direct delete of tombstones failed with err=1 - - delete of entry with only conflict children failed correctly, but gave no hint why - - Fix: update the correct numsobordinates attribut for cenotaphs - set proper flag in directly deleting a tombstone - change search filter for tombstone purging to include ldapsubentries - check for conflict children if a delete is rejected and add a message to the response - - Reviewed by; Thierry, William - thanks ---- - ldap/servers/plugins/replication/repl5_replica.c | 14 +++++++++-- - ldap/servers/plugins/replication/urp.c | 8 +++--- - ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 +++--- - ldap/servers/slapd/back-ldbm/ldbm_delete.c | 14 ++++++++--- - ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 3 ++- - ldap/servers/slapd/back-ldbm/parents.c | 12 ++++++--- - ldap/servers/slapd/entry.c | 31 ++++++++++++++++++++++++ - ldap/servers/slapd/slapi-plugin.h | 2 ++ - ldap/servers/slapd/slapi-private.h | 1 + - ldap/servers/slapd/task.c | 4 +-- - 10 files changed, 78 insertions(+), 19 deletions(-) - -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index bdb8a5167..628fb9ceb 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -3017,6 +3017,16 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data) - search in the future, see _replica_reap_tombstones below and add more to the - attrs array */ - deletion_csn = entry_get_deletion_csn(entry); -+ if (deletion_csn == NULL) { -+ /* this might be a tombstone which was directly added, eg a cenotaph -+ * check if a tombstonecsn exist and use it -+ */ -+ char *tombstonecsn = slapi_entry_attr_get_charptr(entry, SLAPI_ATTR_TOMBSTONE_CSN); -+ if (tombstonecsn) { -+ deletion_csn = csn_new_by_string(tombstonecsn); -+ slapi_ch_free_string(&tombstonecsn); -+ } -+ } - - if ((NULL == deletion_csn || csn_compare(deletion_csn, purge_csn) < 0) && - (!is_ruv_tombstone_entry(entry))) { -@@ -3116,11 +3126,11 @@ _replica_reap_tombstones(void *arg) - */ - csn_as_string(purge_csn, PR_FALSE, deletion_csn_str); - PR_snprintf(tombstone_filter, 128, -- "(&(%s<=%s)(objectclass=nsTombstone))", SLAPI_ATTR_TOMBSTONE_CSN, -+ "(&(%s<=%s)(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))", SLAPI_ATTR_TOMBSTONE_CSN, - csn_as_string(purge_csn, PR_FALSE, deletion_csn_str)); - } else { - /* Use the old inefficient filter */ -- PR_snprintf(tombstone_filter, 128, "(objectclass=nsTombstone)"); -+ PR_snprintf(tombstone_filter, 128, "(&(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))"); - } - - /* we just need the objectclass - for the deletion csn -diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c -index d4556d7fd..11c5da7cf 100644 ---- a/ldap/servers/plugins/replication/urp.c -+++ b/ldap/servers/plugins/replication/urp.c -@@ -911,7 +911,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn) - cenotaph, - NULL, - repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), -- OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP); -+ OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY); - slapi_add_internal_pb(add_pb); - slapi_pblock_get(add_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret); - -@@ -1922,7 +1922,7 @@ done: - newpb = NULL; - - slapi_log_err(SLAPI_LOG_REPL, sessionid, -- "urp_get_min_naming_conflict_entry - Found %d entries\n", i); -+ "urp_get_min_naming_conflict_entry - Found %d entries\n", min_csn?1:0); - - return min_naming_conflict_entry; - } -@@ -2172,8 +2172,8 @@ mod_objectclass_attr(const char *uniqueid, const Slapi_DN *entrysdn, const Slapi - char csnstr[CSN_STRSIZE+1] = {0}; - - slapi_mods_init(&smods, 3); -- slapi_mods_add(&smods, LDAP_MOD_ADD, "objectclass", strlen("ldapsubentry"),"ldapsubentry"); -- slapi_mods_add(&smods, LDAP_MOD_REPLACE, "conflictcsn", CSN_STRSIZE, csn_as_string(opcsn, PR_FALSE, csnstr)); -+ slapi_mods_add_string(&smods, LDAP_MOD_ADD, "objectclass", "ldapsubentry"); -+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "conflictcsn", csn_as_string(opcsn, PR_FALSE, csnstr)); - op_result = urp_fixup_modify_entry(uniqueid, entrysdn, opcsn, &smods, 0); - slapi_mods_done(&smods); - if (op_result == LDAP_TYPE_OR_VALUE_EXISTS) { -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c -index c93d44a65..f0a3262ec 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c -@@ -81,6 +81,7 @@ ldbm_back_add(Slapi_PBlock *pb) - Slapi_Operation *operation; - int is_replicated_operation = 0; - int is_resurect_operation = 0; -+ int is_cenotaph_operation = 0; - int is_tombstone_operation = 0; - int is_fixup_operation = 0; - int is_remove_from_cache = 0; -@@ -116,6 +117,7 @@ ldbm_back_add(Slapi_PBlock *pb) - } - - is_resurect_operation = operation_is_flag_set(operation, OP_FLAG_RESURECT_ENTRY); -+ is_cenotaph_operation = operation_is_flag_set(operation, OP_FLAG_CENOTAPH_ENTRY); - is_tombstone_operation = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY); - is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP); - is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV); -@@ -846,9 +848,9 @@ ldbm_back_add(Slapi_PBlock *pb) - the in-memory state of the parent to reflect the new child (update - subordinate count specifically */ - if (parententry) { -- retval = parent_update_on_childchange(&parent_modify_c, -- is_resurect_operation ? PARENTUPDATE_RESURECT : PARENTUPDATE_ADD, -- NULL); -+ int op = is_resurect_operation ? PARENTUPDATE_RESURECT : PARENTUPDATE_ADD; -+ if (is_cenotaph_operation ) op |= PARENTUPDATE_CREATE_TOMBSTONE; -+ retval = parent_update_on_childchange(&parent_modify_c, op, NULL); - slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_add", - "conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n", - conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval); -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -index be0db1bd0..bc0a3654e 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c -@@ -291,9 +291,16 @@ replace_entry: - retval = slapi_entry_has_children(e->ep_entry); - if (retval && !is_replicated_operation) { - ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF; -- slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_delete", -- "conn=%lu op=%d Deleting entry %s has %d children.\n", -- conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval); -+ if (slapi_entry_has_conflict_children(e->ep_entry, (void *)li->li_identity) > 0) { -+ ldap_result_message = "Entry has replication conflicts as children"; -+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete", -+ "conn=%lu op=%d Deleting entry %s has replication conflicts as children.\n", -+ conn_id, op_id, slapi_entry_get_dn(e->ep_entry)); -+ } else { -+ slapi_log_err(SLAPI_LOG_BACKLDBM, "ldbm_back_delete", -+ "conn=%lu op=%d Deleting entry %s has %d children.\n", -+ conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval); -+ } - retval = -1; - goto error_return; - } -@@ -431,6 +438,7 @@ replace_entry: - slapi_log_err(SLAPI_LOG_WARNING, "ldbm_back_delete", - "Attempt to Tombstone again a tombstone entry %s\n", dn); - delete_tombstone_entry = 1; -+ operation_set_flag(operation, OP_FLAG_TOMBSTONE_ENTRY); - } - } - -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c -index b41a2d241..5797dd779 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c -@@ -2824,7 +2824,8 @@ _entryrdn_delete_key(backend *be, - break; - } - childelem = (rdn_elem *)dataret.data; -- if (!slapi_is_special_rdn(childelem->rdn_elem_nrdn_rdn, RDN_IS_TOMBSTONE)) { -+ if (!slapi_is_special_rdn(childelem->rdn_elem_nrdn_rdn, RDN_IS_TOMBSTONE) && -+ !strcasestr(childelem->rdn_elem_nrdn_rdn, "cenotaphid")) { - /* there's at least one live child */ - slapi_log_err(SLAPI_LOG_ERR, "_entryrdn_delete_key", - "Failed to remove %s; has a child %s\n", nrdn, -diff --git a/ldap/servers/slapd/back-ldbm/parents.c b/ldap/servers/slapd/back-ldbm/parents.c -index 79e66451e..1afc795c0 100644 ---- a/ldap/servers/slapd/back-ldbm/parents.c -+++ b/ldap/servers/slapd/back-ldbm/parents.c -@@ -89,7 +89,11 @@ parent_update_on_childchange(modify_context *mc, int op, size_t *new_sub_count) - } - } - -- if (PARENTUPDATE_DELETE_TOMBSTONE != repl_op) { -+ if ((PARENTUPDATE_ADD == op) && (PARENTUPDATE_CREATE_TOMBSTONE == repl_op)) { -+ /* we are directly adding a tombstone entry, only need to -+ * update the tombstone subordinates -+ */ -+ } else if (PARENTUPDATE_DELETE_TOMBSTONE != repl_op) { - /* are we adding ? */ - if (((PARENTUPDATE_ADD == op) || (PARENTUPDATE_RESURECT == op)) && !already_present) { - /* If so, and the parent entry does not already have a subcount -@@ -136,10 +140,10 @@ parent_update_on_childchange(modify_context *mc, int op, size_t *new_sub_count) - } - } - -- /* tombstoneNumSubordinates is needed only when this is repl op -- * and a child is being deleted */ -+ /* tombstoneNumSubordinates has to be updated if a tombstone child has been -+ * deleted or a tombstone has been directly added (cenotaph) */ - current_sub_count = LDAP_MAXINT; -- if ((repl_op && (PARENTUPDATE_DEL == op)) || (PARENTUPDATE_RESURECT == op)) { -+ if (repl_op) { - ret = slapi_entry_attr_find(mc->old_entry->ep_entry, - tombstone_numsubordinates, &read_attr); - if (0 == ret) { -diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c -index 32828b4e2..b85e9f5b0 100644 ---- a/ldap/servers/slapd/entry.c -+++ b/ldap/servers/slapd/entry.c -@@ -3238,6 +3238,37 @@ slapi_entry_has_children(const Slapi_Entry *entry) - return slapi_entry_has_children_ext(entry, 0); - } - -+int -+slapi_entry_has_conflict_children(const Slapi_Entry *entry, void *plg_id) -+{ -+ Slapi_PBlock *search_pb = NULL; -+ Slapi_Entry **entries; -+ int rc = 0; -+ -+ search_pb = slapi_pblock_new(); -+ slapi_search_internal_set_pb(search_pb, slapi_entry_get_dn_const(entry), -+ LDAP_SCOPE_ONELEVEL, -+ "(&(objectclass=ldapsubentry)(nsds5ReplConflict=namingConflict*))", -+ NULL, 0, NULL, NULL, plg_id, 0); -+ slapi_search_internal_pb(search_pb); -+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); -+ if (rc) { -+ rc = -1; -+ } else { -+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); -+ if (entries && entries[0]) { -+ /* we found at least one conflict entry */ -+ rc = 1; -+ } else { -+ rc = 0; -+ } -+ slapi_free_search_results_internal(search_pb); -+ } -+ slapi_pblock_destroy(search_pb); -+ -+ return rc; -+} -+ - /* - * Renames an entry to simulate a MODRDN operation - */ -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index 95cdcc0da..6978e258f 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -2000,6 +2000,8 @@ int slapi_entry_has_children(const Slapi_Entry *e); - */ - int slapi_entry_has_children_ext(const Slapi_Entry *e, int include_tombstone); - -+int slapi_entry_has_conflict_children(const Slapi_Entry *e, void *plg_id); -+ - /** - * This function determines if an entry is the root DSE. - * -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index 548d5cabb..b08c0d7ce 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -403,6 +403,7 @@ char *slapi_filter_to_string_internal(const struct slapi_filter *f, char *buf, s - #define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x000800 */ - #define OP_FLAG_TOMBSTONE_ENTRY SLAPI_OP_FLAG_TOMBSTONE_ENTRY /* 0x001000 */ - #define OP_FLAG_RESURECT_ENTRY 0x002000 -+#define OP_FLAG_CENOTAPH_ENTRY 0x004000 - #define OP_FLAG_ACTION_NOLOG 0x008000 /* Do not log the entry in \ - * audit log or change log \ - */ -diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c -index 4bd8895ff..3f9d5d995 100644 ---- a/ldap/servers/slapd/task.c -+++ b/ldap/servers/slapd/task.c -@@ -2352,10 +2352,10 @@ task_fixup_tombstone_thread(void *arg) - - if (task_data->stripcsn) { - /* find tombstones with nsTombstoneCSN */ -- filter = "(&(nstombstonecsn=*)(objectclass=nsTombstone))"; -+ filter = "(&(nstombstonecsn=*)(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))"; - } else { - /* find tombstones missing nsTombstoneCSN */ -- filter = "(&(!(nstombstonecsn=*))(objectclass=nsTombstone))"; -+ filter = "(&(!(nstombstonecsn=*))(objectclass=nsTombstone)(|(objectclass=*)(objectclass=ldapsubentry)))"; - } - - /* Okay check the specified backends only */ --- -2.13.6 - diff --git a/SOURCES/0068-Ticket-49380-Add-CI-test.patch b/SOURCES/0068-Ticket-49380-Add-CI-test.patch new file mode 100644 index 0000000..d59e7bf --- /dev/null +++ b/SOURCES/0068-Ticket-49380-Add-CI-test.patch @@ -0,0 +1,81 @@ +From d336e3558655d44f8ba797392af882e33d492958 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0068-Ticket-49551-fix-memory-leak-found-by-coverity.patch b/SOURCES/0068-Ticket-49551-fix-memory-leak-found-by-coverity.patch deleted file mode 100644 index efa2ee4..0000000 --- a/SOURCES/0068-Ticket-49551-fix-memory-leak-found-by-coverity.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a88eea7e06a8e0a7367b2d266f9db37f6d5bbb4a Mon Sep 17 00:00:00 2001 -From: Ludwig Krispenz -Date: Mon, 12 Feb 2018 16:27:03 +0100 -Subject: [PATCH] Ticket 49551 - fix memory leak found by coverity - ---- - ldap/servers/plugins/replication/repl5_replica.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index 628fb9ceb..e3ddd783d 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -3002,6 +3002,7 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data) - if the value is set in the replica, we will know about it immediately */ - PRBool *tombstone_reap_stop = ((reap_callback_data *)cb_data)->tombstone_reap_stop; - const CSN *deletion_csn = NULL; -+ int deletion_csn_free = 0; - int rc = -1; - - /* abort reaping if we've been told to stop or we're shutting down */ -@@ -3024,6 +3025,7 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data) - char *tombstonecsn = slapi_entry_attr_get_charptr(entry, SLAPI_ATTR_TOMBSTONE_CSN); - if (tombstonecsn) { - deletion_csn = csn_new_by_string(tombstonecsn); -+ deletion_csn_free = 1; - slapi_ch_free_string(&tombstonecsn); - } - } -@@ -3056,6 +3058,9 @@ process_reap_entry(Slapi_Entry *entry, void *cb_data) - /* Don't update the count for the database tombstone entry */ - (*num_entriesp)++; - } -+ if (deletion_csn_free) { -+ csn_free(&deletion_csn); -+ } - - return 0; - } --- -2.13.6 - diff --git a/SOURCES/0069-Ticket-49327-password-expired-control-not-sent-durin.patch b/SOURCES/0069-Ticket-49327-password-expired-control-not-sent-durin.patch new file mode 100644 index 0000000..e4b182a --- /dev/null +++ b/SOURCES/0069-Ticket-49327-password-expired-control-not-sent-durin.patch @@ -0,0 +1,610 @@ +From 3ab8a78cd27cc8d2ad7a2b322a4fe73c43a3db08 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0070-Ticket-49379-Allowed-sasl-mapping-requires-restart.patch b/SOURCES/0070-Ticket-49379-Allowed-sasl-mapping-requires-restart.patch new file mode 100644 index 0000000..c2e230b --- /dev/null +++ b/SOURCES/0070-Ticket-49379-Allowed-sasl-mapping-requires-restart.patch @@ -0,0 +1,439 @@ +From 8a7b47602acc910d2f64439b81af3299b60359c8 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0071-Fix-cherry-pick-error-from-sasl-mech-commit.patch b/SOURCES/0071-Fix-cherry-pick-error-from-sasl-mech-commit.patch new file mode 100644 index 0000000..b32ef38 --- /dev/null +++ b/SOURCES/0071-Fix-cherry-pick-error-from-sasl-mech-commit.patch @@ -0,0 +1,31 @@ +From 4a51a17762fb4e7ce1beb0600916fed8b45a5483 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0072-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch b/SOURCES/0072-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch new file mode 100644 index 0000000..d97bb51 --- /dev/null +++ b/SOURCES/0072-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch @@ -0,0 +1,322 @@ +From 2741a6db134ad40662cfa0233c4542d2d4148997 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0073-Ticket-49180-backport-1.3.6-errors-log-filled-with-a.patch b/SOURCES/0073-Ticket-49180-backport-1.3.6-errors-log-filled-with-a.patch new file mode 100644 index 0000000..ae197fb --- /dev/null +++ b/SOURCES/0073-Ticket-49180-backport-1.3.6-errors-log-filled-with-a.patch @@ -0,0 +1,50 @@ +From 1787e9ffda09f9ec8518ceaede5cf1ef014c5d17 Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +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; jreplica_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 + diff --git a/SOURCES/0074-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch b/SOURCES/0074-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch new file mode 100644 index 0000000..36fab2f --- /dev/null +++ b/SOURCES/0074-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch @@ -0,0 +1,39 @@ +From 91c80c06affa3f4bfe106d2291efc360ab2b421d Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0075-Ticket-49401-improve-valueset-sorted-performance-on-.patch b/SOURCES/0075-Ticket-49401-improve-valueset-sorted-performance-on-.patch new file mode 100644 index 0000000..f385154 --- /dev/null +++ b/SOURCES/0075-Ticket-49401-improve-valueset-sorted-performance-on-.patch @@ -0,0 +1,248 @@ +From 64b9d015523b4ae379ff2d72fc73da173be8a712 Mon Sep 17 00:00:00 2001 +From: Mohammad Nweider +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; inum; 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 + diff --git a/SOURCES/0076-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch b/SOURCES/0076-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch new file mode 100644 index 0000000..08fdf39 --- /dev/null +++ b/SOURCES/0076-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch @@ -0,0 +1,54 @@ +From 43c73ca572af6a4bdc9b5994a9640f4d4e713cc2 Mon Sep 17 00:00:00 2001 +From: Mohammad Nweider +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 +(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 + diff --git a/SOURCES/0077-Ticket-48235-Remove-memberOf-global-lock.patch b/SOURCES/0077-Ticket-48235-Remove-memberOf-global-lock.patch new file mode 100644 index 0000000..2dccc5c --- /dev/null +++ b/SOURCES/0077-Ticket-48235-Remove-memberOf-global-lock.patch @@ -0,0 +1,874 @@ +From 229f61f5f54aeb9e1a1756f731dfe7bcedbf148c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 +- + #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 + diff --git a/SOURCES/0078-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch b/SOURCES/0078-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch new file mode 100644 index 0000000..a0a24dc --- /dev/null +++ b/SOURCES/0078-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch @@ -0,0 +1,41 @@ +From bc190eeaaffbb514f69664b4d033dc593a78683b Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0079-Ticket-49439-cleanallruv-is-not-logging-information.patch b/SOURCES/0079-Ticket-49439-cleanallruv-is-not-logging-information.patch new file mode 100644 index 0000000..da266a6 --- /dev/null +++ b/SOURCES/0079-Ticket-49439-cleanallruv-is-not-logging-information.patch @@ -0,0 +1,239 @@ +From 8031684255007b42df3d08b80e674aefb0ebfb2d Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0080-Ticket-49436-double-free-in-COS-in-some-conditions.patch b/SOURCES/0080-Ticket-49436-double-free-in-COS-in-some-conditions.patch new file mode 100644 index 0000000..fc70af1 --- /dev/null +++ b/SOURCES/0080-Ticket-49436-double-free-in-COS-in-some-conditions.patch @@ -0,0 +1,1008 @@ +From fc9a206c294fb5ea2401a9365f01ef2565799478 Mon Sep 17 00:00:00 2001 +From: William Brown +Date: Thu, 2 Nov 2017 13:32:41 +1000 +Subject: [PATCH] Ticket 49436 - double free in COS in some conditions + +Bug Description: virtualattrs and COS have some serious memory +ownership issues. What was happening is that COS with multiple +attributes using the same sp_handle would cause a structure +to be registered twice. During shutdown we would then trigger +a double free in the process. + +Fix Description: Change the behaviour of sp_handles to use a +handle *per* attribute we register to guarantee the assocation +between them. + +https://pagure.io/389-ds-base/issue/49436 + +Author: wibrown + +Review by: mreynolds, vashirov (Thanks!) + +(cherry pick from commit ee4428a3f5d2d8e37a7107c7dce9d622fc17d41c) +--- + dirsrvtests/tests/suites/cos/indirect_cos_test.py | 43 +- + ldap/servers/plugins/cos/cos_cache.c | 723 +++++++++++----------- + ldap/servers/plugins/roles/roles_cache.c | 50 +- + ldap/servers/slapd/vattr.c | 34 +- + 4 files changed, 406 insertions(+), 444 deletions(-) + +diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py +index 1aac6b8ed..452edcdf8 100644 +--- a/dirsrvtests/tests/suites/cos/indirect_cos_test.py ++++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py +@@ -7,6 +7,7 @@ import subprocess + + from lib389 import Entry + from lib389.idm.user import UserAccounts ++from lib389.idm.domain import Domain + from lib389.topologies import topology_st as topo + from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE, + SERVERID_STANDALONE, PORT_STANDALONE) +@@ -48,14 +49,8 @@ def check_user(inst): + def setup_subtree_policy(topo): + """Set up subtree password policy + """ +- try: +- topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, +- 'nsslapd-pwpolicy-local', +- 'on')]) +- except ldap.LDAPError as e: +- log.error('Failed to set fine-grained policy: error {}'.format( +- e.message['desc'])) +- raise e ++ ++ topo.standalone.config.set('nsslapd-pwpolicy-local', 'on') + + log.info('Create password policy for subtree {}'.format(OU_PEOPLE)) + try: +@@ -68,15 +63,9 @@ def setup_subtree_policy(topo): + OU_PEOPLE, e.message['desc'])) + raise e + +- log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE)) +- try: +- topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE, +- 'pwdpolicysubentry', +- PW_POLICY_CONT_PEOPLE2)]) +- except ldap.LDAPError as e: +- log.error('Failed to pwdpolicysubentry pw policy ' +- 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc'])) +- raise e ++ domain = Domain(topo.standalone, DEFAULT_SUFFIX) ++ domain.replace('pwdpolicysubentry', PW_POLICY_CONT_PEOPLE2) ++ + time.sleep(1) + + +@@ -116,12 +105,9 @@ def setup(topo, request): + """ + log.info('Add custom schema...') + try: +- ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " + +- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") +- ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " + +- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") +- OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " + +- "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )") ++ ATTR_1 = (b"( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") ++ ATTR_2 = (b"( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )") ++ OC = (b"( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY ( x-department $ x-en-ou ) X-ORIGIN 'user defined' )") + topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1), + (ldap.MOD_ADD, 'attributeTypes', ATTR_2), + (ldap.MOD_ADD, 'objectClasses', OC)]) +@@ -142,14 +128,9 @@ def setup(topo, request): + 'homeDirectory': '/home/test_user', + 'seeAlso': 'cn=cosTemplate,dc=example,dc=com' + } +- users.create(properties=user_properties) +- try: +- topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD, +- 'objectclass', +- 'xPerson')]) +- except ldap.LDAPError as e: +- log.fatal('Failed to add objectclass to user') +- raise e ++ user = users.create(properties=user_properties) ++ ++ user.add('objectClass', 'xPerson') + + # Setup COS + log.info("Setup indirect COS...") +diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c +index 87d48908c..0e93183d2 100644 +--- a/ldap/servers/plugins/cos/cos_cache.c ++++ b/ldap/servers/plugins/cos/cos_cache.c +@@ -108,9 +108,6 @@ void * cos_get_plugin_identity(void); + #define COSTYPE_INDIRECT 3 + #define COS_DEF_ERROR_NO_TEMPLATES -2 + +-/* the global plugin handle */ +-static volatile vattr_sp_handle *vattr_handle = NULL; +- + /* both variables are protected by change_lock */ + static int cos_cache_notify_flag = 0; + static PRBool cos_cache_at_work = PR_FALSE; +@@ -289,75 +286,61 @@ static Slapi_CondVar *start_cond = NULL; + */ + int cos_cache_init(void) + { +- int ret = 0; +- +- slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_init\n"); +- +- slapi_vattrcache_cache_none(); +- cache_lock = slapi_new_mutex(); +- change_lock = slapi_new_mutex(); +- stop_lock = slapi_new_mutex(); +- something_changed = slapi_new_condvar(change_lock); +- keeprunning =1; +- start_lock = slapi_new_mutex(); +- start_cond = slapi_new_condvar(start_lock); +- started = 0; +- +- if (stop_lock == NULL || +- change_lock == NULL || +- cache_lock == NULL || +- stop_lock == NULL || +- start_lock == NULL || +- start_cond == NULL || +- something_changed == NULL) +- { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, +- "cos_cache_init - Cannot create mutexes\n" ); +- ret = -1; +- goto out; +- } +- +- /* grab the views interface */ +- if(slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) +- { +- /* lets be tolerant if views is disabled */ +- views_api = 0; +- } ++ int ret = 0; + +- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, +- cos_cache_vattr_get, +- cos_cache_vattr_compare, +- cos_cache_vattr_types) != 0) +- { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, +- "cos_cache_init - Cannot register as service provider\n" ); +- ret = -1; +- goto out; +- } ++ slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_init\n"); ++ ++ slapi_vattrcache_cache_none(); ++ cache_lock = slapi_new_mutex(); ++ change_lock = slapi_new_mutex(); ++ stop_lock = slapi_new_mutex(); ++ something_changed = slapi_new_condvar(change_lock); ++ keeprunning = 1; ++ start_lock = slapi_new_mutex(); ++ start_cond = slapi_new_condvar(start_lock); ++ started = 0; ++ ++ if (stop_lock == NULL || ++ change_lock == NULL || ++ cache_lock == NULL || ++ stop_lock == NULL || ++ start_lock == NULL || ++ start_cond == NULL || ++ something_changed == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, ++ "cos_cache_init - Cannot create mutexes\n"); ++ ret = -1; ++ goto out; ++ } + +- if ( PR_CreateThread (PR_USER_THREAD, +- cos_cache_wait_on_change, +- NULL, +- PR_PRIORITY_NORMAL, +- PR_GLOBAL_THREAD, +- PR_UNJOINABLE_THREAD, +- SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL ) +- { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, +- "cos_cache_init - PR_CreateThread failed\n" ); +- ret = -1; +- goto out; +- } ++ /* grab the views interface */ ++ if (slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) { ++ /* lets be tolerant if views is disabled */ ++ views_api = 0; ++ } + +- /* wait for that thread to get started */ +- if (ret == 0) { +- slapi_lock_mutex(start_lock); +- while (!started) { +- while (slapi_wait_condvar(start_cond, NULL) == 0); +- } +- slapi_unlock_mutex(start_lock); +- } ++ if (PR_CreateThread(PR_USER_THREAD, ++ cos_cache_wait_on_change, ++ NULL, ++ PR_PRIORITY_NORMAL, ++ PR_GLOBAL_THREAD, ++ PR_UNJOINABLE_THREAD, ++ SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, ++ "cos_cache_init - PR_CreateThread failed\n"); ++ ret = -1; ++ goto out; ++ } + ++ /* wait for that thread to get started */ ++ if (ret == 0) { ++ slapi_lock_mutex(start_lock); ++ while (!started) { ++ while (slapi_wait_condvar(start_cond, NULL) == 0) ++ ; ++ } ++ slapi_unlock_mutex(start_lock); ++ } + + out: + slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "<-- cos_cache_init\n"); +@@ -752,321 +735,311 @@ struct dn_defs_info { + static int + cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) + { +- struct dn_defs_info *info; +- cosAttrValue **pSneakyVal = 0; +- cosAttrValue *pObjectclass = 0; +- cosAttrValue *pCosTargetTree = 0; +- cosAttrValue *pCosTemplateDn = 0; +- cosAttrValue *pCosSpecifier = 0; +- cosAttrValue *pCosAttribute = 0; +- cosAttrValue *pCosOverrides = 0; +- cosAttrValue *pCosOperational = 0; +- cosAttrValue *pCosOpDefault = 0; +- cosAttrValue *pCosMerge = 0; +- cosAttrValue *pDn = 0; +- struct berval **dnVals; +- int cosType = 0; +- int valIndex = 0; +- Slapi_Attr *dnAttr; +- char *attrType = 0; +- char *norm_dn = NULL; +- info=(struct dn_defs_info *)callback_data; +- +- cos_cache_add_attrval(&pDn, slapi_entry_get_dn(e)); +- if(slapi_entry_first_attr(e, &dnAttr)) { +- goto bail; +- } ++ struct dn_defs_info *info; ++ cosAttrValue **pSneakyVal = 0; ++ cosAttrValue *pObjectclass = 0; ++ cosAttrValue *pCosTargetTree = 0; ++ cosAttrValue *pCosTemplateDn = 0; ++ cosAttrValue *pCosSpecifier = 0; ++ cosAttrValue *pCosAttribute = 0; ++ cosAttrValue *pCosOverrides = 0; ++ cosAttrValue *pCosOperational = 0; ++ cosAttrValue *pCosOpDefault = 0; ++ cosAttrValue *pCosMerge = 0; ++ cosAttrValue *pDn = 0; ++ struct berval **dnVals; ++ int cosType = 0; ++ int valIndex = 0; ++ Slapi_Attr *dnAttr; ++ char *attrType = 0; ++ char *norm_dn = NULL; ++ info = (struct dn_defs_info *)callback_data; ++ ++ cos_cache_add_attrval(&pDn, slapi_entry_get_dn(e)); ++ if (slapi_entry_first_attr(e, &dnAttr)) { ++ goto bail; ++ } + +- do { +- attrType = 0; +- /* we need to fill in the details of the definition now */ +- slapi_attr_get_type(dnAttr, &attrType); +- if(!attrType) { +- continue; +- } +- pSneakyVal = 0; +- if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"objectclass")) +- pSneakyVal = &pObjectclass; +- else if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"cosTargetTree")){ +- if(pCosTargetTree){ +- norm_dn = slapi_create_dn_string("%s", pCosTargetTree->val); +- if(norm_dn){ +- slapi_ch_free_string(&pCosTargetTree->val); +- pCosTargetTree->val = norm_dn; +- } +- } +- pSneakyVal = &pCosTargetTree; +- } else if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"cosTemplateDn")) +- pSneakyVal = &pCosTemplateDn; +- else if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"cosSpecifier")) +- pSneakyVal = &pCosSpecifier; +- else if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"cosAttribute")) +- pSneakyVal = &pCosAttribute; +- else if(!slapi_utf8casecmp((unsigned char*)attrType, (unsigned char*)"cosIndirectSpecifier")) +- pSneakyVal = &pCosSpecifier; +- if(!pSneakyVal) { +- continue; +- } +- /* It's a type we're interested in */ +- if(slapi_attr_get_bervals_copy(dnAttr, &dnVals)) { +- continue; +- } +- valIndex = 0; +- if(!dnVals) { +- continue; +- } +- for (valIndex = 0; dnVals[valIndex]; valIndex++) +- { +- if(!dnVals[valIndex]->bv_val) { +- continue; +- } +- /* +- parse any overide or default values +- and deal with them +- */ +- if(pSneakyVal == &pCosAttribute) +- { +- int qualifier_hit = 0; +- int op_qualifier_hit = 0; +- int merge_schemes_qualifier_hit = 0; +- int override_qualifier_hit =0; +- int default_qualifier_hit = 0; +- int operational_default_qualifier_hit = 0; +- do +- { +- qualifier_hit = 0; ++ do { ++ attrType = 0; ++ /* we need to fill in the details of the definition now */ ++ slapi_attr_get_type(dnAttr, &attrType); ++ if (!attrType) { ++ continue; ++ } ++ pSneakyVal = 0; ++ if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"objectclass")) ++ pSneakyVal = &pObjectclass; ++ else if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"cosTargetTree")) { ++ if (pCosTargetTree) { ++ norm_dn = slapi_create_dn_string("%s", pCosTargetTree->val); ++ if (norm_dn) { ++ slapi_ch_free_string(&pCosTargetTree->val); ++ pCosTargetTree->val = norm_dn; ++ } ++ } ++ pSneakyVal = &pCosTargetTree; ++ } else if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"cosTemplateDn")) ++ pSneakyVal = &pCosTemplateDn; ++ else if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"cosSpecifier")) ++ pSneakyVal = &pCosSpecifier; ++ else if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"cosAttribute")) ++ pSneakyVal = &pCosAttribute; ++ else if (!slapi_utf8casecmp((unsigned char *)attrType, (unsigned char *)"cosIndirectSpecifier")) ++ pSneakyVal = &pCosSpecifier; ++ if (!pSneakyVal) { ++ continue; ++ } ++ /* It's a type we're interested in */ ++ if (slapi_attr_get_bervals_copy(dnAttr, &dnVals)) { ++ continue; ++ } ++ valIndex = 0; ++ if (!dnVals) { ++ continue; ++ } ++ for (valIndex = 0; dnVals[valIndex]; valIndex++) { ++ if (!dnVals[valIndex]->bv_val) { ++ continue; ++ } ++ /* ++ parse any overide or default values ++ and deal with them ++ */ ++ if (pSneakyVal == &pCosAttribute) { ++ int qualifier_hit = 0; ++ int op_qualifier_hit = 0; ++ int merge_schemes_qualifier_hit = 0; ++ int override_qualifier_hit = 0; ++ int default_qualifier_hit = 0; ++ int operational_default_qualifier_hit = 0; ++ do { ++ qualifier_hit = 0; ++ ++ if (cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " operational")) { ++ /* matched */ ++ op_qualifier_hit = 1; ++ qualifier_hit = 1; ++ } ++ ++ if (cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " merge-schemes")) { ++ /* matched */ ++ merge_schemes_qualifier_hit = 1; ++ qualifier_hit = 1; ++ } ++ ++ if (cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " override")) { ++ /* matched */ ++ override_qualifier_hit = 1; ++ qualifier_hit = 1; ++ } ++ ++ if (cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " default")) { ++ default_qualifier_hit = 1; ++ qualifier_hit = 1; ++ } ++ ++ if (cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " operational-default")) { ++ operational_default_qualifier_hit = 1; ++ qualifier_hit = 1; ++ } ++ } while (qualifier_hit == 1); ++ ++ /* ++ * At this point, dnVals[valIndex]->bv_val ++ * is the value of cosAttribute, stripped of ++ * any qualifiers, so add this pure attribute type to ++ * the appropriate lists. ++ */ ++ ++ if (op_qualifier_hit) { ++ cos_cache_add_attrval(&pCosOperational, ++ dnVals[valIndex]->bv_val); ++ } ++ if (merge_schemes_qualifier_hit) { ++ cos_cache_add_attrval(&pCosMerge, dnVals[valIndex]->bv_val); ++ } ++ if (override_qualifier_hit) { ++ cos_cache_add_attrval(&pCosOverrides, ++ dnVals[valIndex]->bv_val); ++ } ++ if (default_qualifier_hit) { ++ /* attr is added below in pSneakyVal, in any case */ ++ } ++ ++ if (operational_default_qualifier_hit) { ++ cos_cache_add_attrval(&pCosOpDefault, ++ dnVals[valIndex]->bv_val); ++ } ++ ++ /* ++ * Each SP_handle is associated to one and only one vattr. ++ * We could consider making this a single function rather ++ * than the double-call. ++ */ ++ ++ vattr_sp_handle *vattr_handle = NULL; ++ ++ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, ++ cos_cache_vattr_get, ++ cos_cache_vattr_compare, ++ cos_cache_vattr_types) != 0) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val); ++ } else { ++ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); ++ } ++ ++ } /* if(attrType is cosAttribute) */ ++ ++ /* ++ * Add the attributetype to the appropriate ++ * list. ++ */ ++ cos_cache_add_attrval(pSneakyVal, dnVals[valIndex]->bv_val); ++ ++ } /* for (valIndex = 0; dnVals[valIndex]; valIndex++) */ ++ ++ ber_bvecfree(dnVals); ++ dnVals = NULL; ++ } while (!slapi_entry_next_attr(e, dnAttr, &dnAttr)); ++ ++ if (pCosAttribute && (!pCosTargetTree || !pCosTemplateDn)) { ++ /* get the parent of the definition */ ++ char *orig = slapi_dn_parent(pDn->val); ++ char *parent = NULL; ++ if (orig) { ++ parent = slapi_create_dn_string("%s", orig); ++ if (!parent) { ++ parent = orig; ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, ++ "cos_dn_defs_cb - " ++ "Failed to normalize parent dn %s. " ++ "Adding the pre normalized dn.\n", ++ parent); ++ } ++ if (!pCosTargetTree) { ++ cos_cache_add_attrval(&pCosTargetTree, parent); ++ } ++ if (!pCosTemplateDn) { ++ cos_cache_add_attrval(&pCosTemplateDn, parent); ++ } ++ if (parent != orig) { ++ slapi_ch_free_string(&parent); ++ } ++ slapi_ch_free_string(&orig); ++ } else { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, ++ "cos_dn_defs_cb - " ++ "Failed to get parent dn of cos definition %s.\n", ++ pDn->val); ++ if (!pCosTemplateDn) { ++ if (!pCosTargetTree) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTargetTree and cosTemplateDn are not set.\n"); ++ } else { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTemplateDn is not set.\n"); ++ } ++ } else if (!pCosTargetTree) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTargetTree is not set.\n"); ++ } ++ } ++ } + +- if(cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " operational")) +- { +- /* matched */ +- op_qualifier_hit = 1; +- qualifier_hit = 1; +- } +- +- if(cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " merge-schemes")) +- { +- /* matched */ +- merge_schemes_qualifier_hit = 1; +- qualifier_hit = 1; +- } ++ /* ++ determine the type of class of service scheme ++ */ + +- if(cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " override")) +- { +- /* matched */ +- override_qualifier_hit = 1; +- qualifier_hit = 1; +- } +- +- if(cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " default")) { +- default_qualifier_hit = 1; +- qualifier_hit = 1; +- } ++ if (pObjectclass) { ++ if (cos_cache_attrval_exists(pObjectclass, "cosDefinition")) { ++ cosType = COSTYPE_CLASSIC; ++ } else if (cos_cache_attrval_exists(pObjectclass, "cosClassicDefinition")) { ++ cosType = COSTYPE_CLASSIC; + +- if(cos_cache_backwards_stricmp_and_clip(dnVals[valIndex]->bv_val, " operational-default")) { +- operational_default_qualifier_hit = 1; +- qualifier_hit = 1; +- } +- } +- while(qualifier_hit == 1); ++ } else if (cos_cache_attrval_exists(pObjectclass, "cosPointerDefinition")) { ++ cosType = COSTYPE_POINTER; + +- /* +- * At this point, dnVals[valIndex]->bv_val +- * is the value of cosAttribute, stripped of +- * any qualifiers, so add this pure attribute type to +- * the appropriate lists. +- */ +- +- if ( op_qualifier_hit ) { +- cos_cache_add_attrval(&pCosOperational, +- dnVals[valIndex]->bv_val); +- } +- if ( merge_schemes_qualifier_hit ) { +- cos_cache_add_attrval(&pCosMerge, dnVals[valIndex]->bv_val); +- } +- if ( override_qualifier_hit ) { +- cos_cache_add_attrval(&pCosOverrides, +- dnVals[valIndex]->bv_val); +- } +- if ( default_qualifier_hit ) { +- /* attr is added below in pSneakyVal, in any case */ +- } ++ } else if (cos_cache_attrval_exists(pObjectclass, "cosIndirectDefinition")) { ++ cosType = COSTYPE_INDIRECT; + +- if ( operational_default_qualifier_hit ) { +- cos_cache_add_attrval(&pCosOpDefault, +- dnVals[valIndex]->bv_val); +- } ++ } else ++ cosType = COSTYPE_BADTYPE; ++ } + +- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, +- dnVals[valIndex]->bv_val, NULL, NULL); +- } /* if(attrType is cosAttribute) */ ++ /* ++ we should now have a full definition, ++ do some sanity checks because we don't ++ want bogus entries in the cache ++ then ship it ++ */ ++ ++ /* these must exist */ ++ if (pDn && pObjectclass && ++ ((cosType == COSTYPE_CLASSIC && ++ pCosTemplateDn && ++ pCosSpecifier && ++ pCosAttribute) || ++ (cosType == COSTYPE_POINTER && ++ pCosTemplateDn && ++ pCosAttribute) || ++ (cosType == COSTYPE_INDIRECT && ++ pCosSpecifier && ++ pCosAttribute))) { ++ int rc = 0; ++ /* ++ we'll leave the referential integrity stuff ++ up to the referint plug-in and assume all ++ is good - if it's not then we just have a ++ useless definition and we'll nag copiously later. ++ */ ++ char *pTmpDn = slapi_ch_strdup(pDn->val); /* because dn gets hosed on error */ ++ ++ if (!(rc = cos_cache_add_defn(info->pDefs, &pDn, cosType, ++ &pCosTargetTree, &pCosTemplateDn, ++ &pCosSpecifier, &pCosAttribute, ++ &pCosOverrides, &pCosOperational, ++ &pCosMerge, &pCosOpDefault))) { ++ info->ret = 0; /* we have succeeded to add the defn*/ ++ } else { ++ /* ++ * Failed but we will continue the search for other defs ++ * Don't reset info->ret....it keeps track of any success ++ */ ++ if (rc == COS_DEF_ERROR_NO_TEMPLATES) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - Skipping CoS Definition %s" ++ "--no CoS Templates found, which should be added before the CoS Definition.\n", ++ pTmpDn); ++ } else { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - Skipping CoS Definition %s\n" ++ "--error(%d)\n", ++ pTmpDn, rc); ++ } ++ } + +- /* +- * Add the attributetype to the appropriate +- * list. +- */ +- cos_cache_add_attrval(pSneakyVal, dnVals[valIndex]->bv_val); +- +- }/* for (valIndex = 0; dnVals[valIndex]; valIndex++) */ +- +- ber_bvecfree( dnVals ); +- dnVals = NULL; +- } while(!slapi_entry_next_attr(e, dnAttr, &dnAttr)); +- +- if (pCosAttribute && (!pCosTargetTree || !pCosTemplateDn)) { +- /* get the parent of the definition */ +- char *orig = slapi_dn_parent(pDn->val); +- char *parent = NULL; +- if (orig) { +- parent = slapi_create_dn_string("%s", orig); +- if (!parent) { +- parent = orig; +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, +- "cos_dn_defs_cb - " +- "Failed to normalize parent dn %s. " +- "Adding the pre normalized dn.\n", +- parent); +- } +- if (!pCosTargetTree) { +- cos_cache_add_attrval(&pCosTargetTree, parent); +- } +- if (!pCosTemplateDn) { +- cos_cache_add_attrval(&pCosTemplateDn, parent); +- } +- if (parent != orig) { +- slapi_ch_free_string(&parent); +- } +- slapi_ch_free_string(&orig); +- } else { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, +- "cos_dn_defs_cb - " +- "Failed to get parent dn of cos definition %s.\n", +- pDn->val); +- if (!pCosTemplateDn) { +- if (!pCosTargetTree) { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTargetTree and cosTemplateDn are not set.\n"); +- } else { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTemplateDn is not set.\n"); +- } +- } else if (!pCosTargetTree) { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - cosTargetTree is not set.\n"); +- } +- } +- } +- +- /* +- determine the type of class of service scheme +- */ +- +- if(pObjectclass) +- { +- if(cos_cache_attrval_exists(pObjectclass, "cosDefinition")) +- { +- cosType = COSTYPE_CLASSIC; +- } +- else if(cos_cache_attrval_exists(pObjectclass, "cosClassicDefinition")) +- { +- cosType = COSTYPE_CLASSIC; +- +- } +- else if(cos_cache_attrval_exists(pObjectclass, "cosPointerDefinition")) +- { +- cosType = COSTYPE_POINTER; +- +- } +- else if(cos_cache_attrval_exists(pObjectclass, "cosIndirectDefinition")) +- { +- cosType = COSTYPE_INDIRECT; +- +- } +- else +- cosType = COSTYPE_BADTYPE; +- } +- +- /* +- we should now have a full definition, +- do some sanity checks because we don't +- want bogus entries in the cache +- then ship it +- */ +- +- /* these must exist */ +- if(pDn && pObjectclass && +- ( +- (cosType == COSTYPE_CLASSIC && +- pCosTemplateDn && +- pCosSpecifier && +- pCosAttribute ) +- || +- (cosType == COSTYPE_POINTER && +- pCosTemplateDn && +- pCosAttribute ) +- || +- (cosType == COSTYPE_INDIRECT && +- pCosSpecifier && +- pCosAttribute ) +- ) +- ) +- { +- int rc = 0; +- /* +- we'll leave the referential integrity stuff +- up to the referint plug-in and assume all +- is good - if it's not then we just have a +- useless definition and we'll nag copiously later. +- */ +- char *pTmpDn = slapi_ch_strdup(pDn->val); /* because dn gets hosed on error */ +- +- if(!(rc = cos_cache_add_defn(info->pDefs, &pDn, cosType, +- &pCosTargetTree, &pCosTemplateDn, +- &pCosSpecifier, &pCosAttribute, +- &pCosOverrides, &pCosOperational, +- &pCosMerge, &pCosOpDefault))) { +- info->ret = 0; /* we have succeeded to add the defn*/ +- } else { +- /* +- * Failed but we will continue the search for other defs +- * Don't reset info->ret....it keeps track of any success +- */ +- if ( rc == COS_DEF_ERROR_NO_TEMPLATES) { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - Skipping CoS Definition %s" +- "--no CoS Templates found, which should be added before the CoS Definition.\n", +- pTmpDn); +- } else { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - Skipping CoS Definition %s\n" +- "--error(%d)\n", +- pTmpDn, rc); +- } +- } +- +- slapi_ch_free_string(&pTmpDn); +- } +- else +- { +- /* +- this definition is brain dead - bail +- if we have a dn use it to report, if not then *really* bad +- things are going on +- */ +- if(pDn) +- { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - " +- "Incomplete cos definition detected in %s, discarding from cache.\n",pDn->val); +- } +- else +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - " +- "Incomplete cos definition detected, no DN to report, discarding from cache.\n"); +- +- if(pCosTargetTree) +- cos_cache_del_attrval_list(&pCosTargetTree); +- if(pCosTemplateDn) +- cos_cache_del_attrval_list(&pCosTemplateDn); +- if(pCosSpecifier) +- cos_cache_del_attrval_list(&pCosSpecifier); +- if(pCosAttribute) +- cos_cache_del_attrval_list(&pCosAttribute); +- if(pDn) +- cos_cache_del_attrval_list(&pDn); +- } ++ slapi_ch_free_string(&pTmpDn); ++ } else { ++ /* ++ this definition is brain dead - bail ++ if we have a dn use it to report, if not then *really* bad ++ things are going on ++ */ ++ if (pDn) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - " ++ "Incomplete cos definition detected in %s, discarding from cache.\n", ++ pDn->val); ++ } else ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_dn_defs_cb - " ++ "Incomplete cos definition detected, no DN to report, discarding from cache.\n"); ++ ++ if (pCosTargetTree) ++ cos_cache_del_attrval_list(&pCosTargetTree); ++ if (pCosTemplateDn) ++ cos_cache_del_attrval_list(&pCosTemplateDn); ++ if (pCosSpecifier) ++ cos_cache_del_attrval_list(&pCosSpecifier); ++ if (pCosAttribute) ++ cos_cache_del_attrval_list(&pCosAttribute); ++ if (pDn) ++ cos_cache_del_attrval_list(&pDn); ++ } + bail: + /* we don't keep the objectclasses, so lets free them */ + if(pObjectclass) { +diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c +index 3697eaa97..3e1724963 100644 +--- a/ldap/servers/plugins/roles/roles_cache.c ++++ b/ldap/servers/plugins/roles/roles_cache.c +@@ -48,9 +48,6 @@ static char *allUserAttributes[] = { + /* views scoping */ + static void **views_api; + +-/* Service provider handler */ +-static vattr_sp_handle *vattr_handle = NULL; +- + /* List of nested roles */ + typedef struct _role_object_nested { + Slapi_DN *dn; /* value of attribute nsroledn in a nested role definition */ +@@ -224,13 +221,16 @@ int roles_cache_init() + + /* Register a callback on backends creation|modification|deletion, + so that we update the corresponding cache */ +- slapi_register_backend_state_change(NULL, roles_cache_trigger_update_suffix); +- +- if ( slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, +- roles_sp_get_value, +- roles_sp_compare_value, +- roles_sp_list_types) ) +- { ++ slapi_register_backend_state_change(NULL, roles_cache_trigger_update_suffix); ++ ++ /* Service provider handler - only used once! and freed by vattr! */ ++ vattr_sp_handle *vattr_handle = NULL; ++ ++ ++ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, ++ roles_sp_get_value, ++ roles_sp_compare_value, ++ roles_sp_list_types)) { + slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, + "roles_cache_init - slapi_vattrspi_register failed\n"); + +@@ -648,22 +648,20 @@ void roles_cache_stop() + + slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "--> roles_cache_stop\n"); + +- /* Go through all the roles list and trigger the associated structure */ +- slapi_rwlock_wrlock(global_lock); +- current_role = roles_list; +- while ( current_role ) +- { +- slapi_lock_mutex(current_role->change_lock); +- current_role->keeprunning = 0; +- next_role = current_role->next; +- slapi_notify_condvar(current_role->something_changed, 1 ); +- slapi_unlock_mutex(current_role->change_lock); +- +- current_role = next_role; +- } +- slapi_rwlock_unlock(global_lock); +- slapi_ch_free((void **)&vattr_handle); +- roles_list = NULL; ++ /* Go through all the roles list and trigger the associated structure */ ++ slapi_rwlock_wrlock(global_lock); ++ current_role = roles_list; ++ while (current_role) { ++ slapi_lock_mutex(current_role->change_lock); ++ current_role->keeprunning = 0; ++ next_role = current_role->next; ++ slapi_notify_condvar(current_role->something_changed, 1); ++ slapi_unlock_mutex(current_role->change_lock); ++ ++ current_role = next_role; ++ } ++ slapi_rwlock_unlock(global_lock); ++ roles_list = NULL; + + slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<-- roles_cache_stop\n"); + } +diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c +index ef4d7f279..84e01cd62 100644 +--- a/ldap/servers/slapd/vattr.c ++++ b/ldap/servers/slapd/vattr.c +@@ -1843,8 +1843,15 @@ static int vattr_map_create(void) + return 0; + } + +-void vattr_map_entry_free(vattr_map_entry *vae) { +- slapi_ch_free((void **)&(vae->sp_list)); ++void ++vattr_map_entry_free(vattr_map_entry *vae) ++{ ++ vattr_sp_handle *list_entry = vae->sp_list; ++ while (list_entry != NULL) { ++ vattr_sp_handle *next_entry = list_entry->next; ++ slapi_ch_free((void **)&list_entry); ++ list_entry = next_entry; ++ } + slapi_ch_free_string(&(vae->type_name)); + slapi_ch_free((void **)&vae); + } +@@ -2134,16 +2141,9 @@ int slapi_vattr_schema_check_type(Slapi_Entry *e, char *type) + + vattr_map_entry *vattr_map_entry_new(char *type_name, vattr_sp_handle *sph, void* hint) + { +- vattr_map_entry *result = NULL; +- vattr_sp_handle *sp_copy = NULL; +- +- sp_copy = (vattr_sp_handle*)slapi_ch_calloc(1, sizeof (vattr_sp_handle)); +- sp_copy->sp = sph->sp; +- sp_copy->hint = hint; +- +- result = (vattr_map_entry*)slapi_ch_calloc(1, sizeof (vattr_map_entry)); +- result->type_name = slapi_ch_strdup(type_name); +- result->sp_list = sp_copy; ++ vattr_map_entry *result = (vattr_map_entry *)slapi_ch_calloc(1, sizeof(vattr_map_entry)); ++ result->type_name = slapi_ch_strdup(type_name); ++ result->sp_list = sph; + + /* go get schema */ + result->objectclasses = vattr_map_entry_build_schema(type_name); +@@ -2259,6 +2259,16 @@ we'd need to hold a lock on the read path, which we don't want to do. + So any SP which relinquishes its need to handle a type needs to continue + to handle the calls on it, but return nothing */ + /* DBDB need to sort out memory ownership here, it's not quite right */ ++/* ++ * This function was inconsistent. We would allocated and "kind of", ++ * copy the sp_handle here for the vattr_map_entry_new path. But we ++ * would "take ownership" for the existing entry and the list addition ++ * path. Instead now, EVERY sp_handle we take, we take ownership of ++ * and the CALLER must allocate a new one each time. ++ * ++ * Better idea, is that regattr should just take the fn pointers ++ * and callers never *see* the sp_handle structure at all. ++ */ + + int vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint) + { +-- +2.13.6 + diff --git a/SOURCES/0081-Ticket-49441-Import-crashes-with-large-indexed-binar.patch b/SOURCES/0081-Ticket-49441-Import-crashes-with-large-indexed-binar.patch new file mode 100644 index 0000000..3e65c49 --- /dev/null +++ b/SOURCES/0081-Ticket-49441-Import-crashes-with-large-indexed-binar.patch @@ -0,0 +1,96 @@ +From df5000efced2d00aa0fc6546fcf6fc7b02e27256 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +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 + diff --git a/SOURCES/0082-Ticket-49431-replicated-MODRDN-fails-breaking-replic.patch b/SOURCES/0082-Ticket-49431-replicated-MODRDN-fails-breaking-replic.patch new file mode 100644 index 0000000..502dda1 --- /dev/null +++ b/SOURCES/0082-Ticket-49431-replicated-MODRDN-fails-breaking-replic.patch @@ -0,0 +1,38 @@ +From 557f4d4ed5e37f09691d383dd8189b642ade8f2b Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +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 + diff --git a/SOURCES/0083-Ticket-49410-opened-connection-can-remain-no-longer-.patch b/SOURCES/0083-Ticket-49410-opened-connection-can-remain-no-longer-.patch new file mode 100644 index 0000000..a94aa80 --- /dev/null +++ b/SOURCES/0083-Ticket-49410-opened-connection-can-remain-no-longer-.patch @@ -0,0 +1,58 @@ +From 72f541fd317321fbd0395dcaa77830aa8b5d35b6 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Wed, 15 Nov 2017 16:38:28 +0100 +Subject: [PATCH] Ticket 49410 - opened connection can remain no longer poll, + like hanging + +Bug Description: + Some opened connection are no longer poll. + Those connections has 'gettingber' toggle set although there is + no more worker thread reading it. + The reason they have gettingber set is that the last + operation had 'persistent search' flag. With such flag + gettingber is not reset. + persistent flag is set even when no persistent search/sync_repl + was received on the connection. + The problem is that the flag is tested on the wrong operation. + The tested operation can be + - the first operation when the connection entered in turbo mode + - the previous operation if several ops PDUs were read on the network + - accessing random memory + + In theory testing the flag can lead to sigsev even + if it never crash + +Fix Description: + The fix is to use the operation that is in the pblock + In such case pb_op is no longer used, so we can get rid of it. + In addition make pb_conn a local variable where it is used + +https://pagure.io/389-ds-base/issue/49410 + +Reviewed by: Ludwig Krispenz, Mark Reynolds + +Platforms tested: F26 + +Flag Day: no + +Doc impact: no +--- + ldap/servers/slapd/connection.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index 359b59a4d..c00c88578 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -1540,6 +1540,8 @@ connection_threadmain() + } + + if (!thread_turbo_flag && !more_data) { ++ Connection *pb_conn = NULL; ++ + /* If more data is left from the previous connection_read_operation, + we should finish the op now. Client might be thinking it's + done sending the request and wait for the response forever. +-- +2.13.6 + diff --git a/SOURCES/0084-Ticket-48118-backport-changelog-can-be-erronously-re.patch b/SOURCES/0084-Ticket-48118-backport-changelog-can-be-erronously-re.patch new file mode 100644 index 0000000..14787e1 --- /dev/null +++ b/SOURCES/0084-Ticket-48118-backport-changelog-can-be-erronously-re.patch @@ -0,0 +1,237 @@ +From b0d593b001d4ef1fb19348335fb39bd45b31764c Mon Sep 17 00:00:00 2001 +From: Ludwig Krispenz +Date: Fri, 8 Dec 2017 14:26:06 +0100 +Subject: [PATCH] Ticket 48118 - backport - changelog can be erronously rebuilt + at startup + +--- + ldap/servers/plugins/replication/cl5_api.c | 39 ++++++++++++++++++++++ + ldap/servers/plugins/replication/repl5.h | 1 - + ldap/servers/plugins/replication/repl5_replica.c | 39 ++-------------------- + .../plugins/replication/repl5_replica_config.c | 2 -- + 4 files changed, 41 insertions(+), 40 deletions(-) + +diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c +index 5c2233f82..1ce8d081f 100644 +--- a/ldap/servers/plugins/replication/cl5_api.c ++++ b/ldap/servers/plugins/replication/cl5_api.c +@@ -304,6 +304,8 @@ static void _cl5ReadBerval (struct berval *bv, char** buff); + static void _cl5WriteBerval (struct berval *bv, char** buff); + static int _cl5ReadBervals (struct berval ***bv, char** buff, unsigned int size); + static int _cl5WriteBervals (struct berval **bv, char** buff, u_int32_t *size); ++static int32_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv); ++static int32_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg); + + /* replay iteration */ + #ifdef FOR_DEBUGGING +@@ -2885,6 +2887,36 @@ static int _cl5WriteBervals (struct berval **bv, char** buff, u_int32_t *size) + return CL5_SUCCESS; + } + ++static int32_t ++_cl5CheckCSNinCL(const ruv_enum_data *element, void *arg) ++{ ++ CL5DBFile *file = (CL5DBFile *)arg; ++ int rc = 0; ++ ++ DBT key = {0}, data = {0}; ++ char csnStr[CSN_STRSIZE]; ++ ++ /* construct the key */ ++ key.data = csn_as_string(element->csn, PR_FALSE, csnStr); ++ key.size = CSN_STRSIZE; ++ ++ data.flags = DB_DBT_MALLOC; ++ ++ rc = file->db->get(file->db, NULL /*txn*/, &key, &data, 0); ++ ++ slapi_ch_free(&(data.data)); ++ return rc; ++} ++ ++static int32_t ++_cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv) ++{ ++ int rc = 0; ++ ++ rc = ruv_enumerate_elements(maxruv, _cl5CheckCSNinCL, (void *)file); ++ ++ return rc; ++} + /* upgrade from db33 to db41 + * 1. Run recovery on the database environment using the DB_ENV->open method + * 2. Remove any Berkeley DB environment using the DB_ENV->remove method +@@ -4248,6 +4280,13 @@ static int _cl5WriteRUV (CL5DBFile *file, PRBool purge) + rc = ruv_to_bervals(file->maxRUV, &vals); + } + ++ if (!purge && _cl5CheckMaxRUV(file, file->maxRUV)) { ++ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, ++ "_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n", ++ file->name); ++ return CL5_DB_ERROR; ++ } ++ + key.size = CSN_STRSIZE; + + rc = _cl5WriteBervals (vals, &buff, &data.size); +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 718f64ef1..9c4789f9e 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -620,7 +620,6 @@ Object *replica_get_for_backend (const char *be_name); + void replica_set_purge_delay (Replica *r, PRUint32 purge_delay); + void replica_set_tombstone_reap_interval (Replica *r, long interval); + void replica_update_ruv_consumer (Replica *r, RUV *supplier_ruv); +-void replica_set_ruv_dirty (Replica *r); + Slapi_Entry *get_in_memory_ruv(Slapi_DN *suffix_sdn); + int replica_write_ruv (Replica *r); + char *replica_get_dn(Replica *r); +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 7927ac30a..3c7281a42 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -46,7 +46,6 @@ struct replica { + char* legacy_purl; /* partial url of the legacy supplier */ + ReplicaId repl_rid; /* replicaID */ + Object *repl_ruv; /* replica update vector */ +- PRBool repl_ruv_dirty; /* Dirty flag for ruv */ + CSNPL *min_csn_pl; /* Pending list for minimal CSN */ + void *csn_pl_reg_id; /* registration assignment for csn callbacks */ + unsigned long repl_state_flags; /* state flags */ +@@ -855,7 +854,6 @@ replica_set_ruv (Replica *r, RUV *ruv) + } + + r->repl_ruv = object_new((void*)ruv, (FNFree)ruv_destroy); +- r->repl_ruv_dirty = PR_TRUE; + + replica_unlock(r->repl_lock); + } +@@ -941,11 +939,6 @@ replica_update_ruv(Replica *r, const CSN *updated_csn, const char *replica_purl) + slapi_sdn_get_dn(r->repl_root), + csn_as_string(updated_csn, PR_FALSE, csn_str)); + } +- else +- { +- /* RUV updated - mark as dirty */ +- r->repl_ruv_dirty = PR_TRUE; +- } + } + else + { +@@ -1526,8 +1519,6 @@ replica_dump(Replica *r) + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tupdate dn: %s\n", + updatedn_list? updatedn_list : "not configured"); + slapi_ch_free_string(&updatedn_list); +- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\truv: %s configured and is %sdirty\n", +- r->repl_ruv ? "" : "not", r->repl_ruv_dirty ? "" : "not "); + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tCSN generator: %s configured\n", + r->repl_csngen ? "" : "not"); + /* JCMREPL - Dump Referrals */ +@@ -1877,7 +1868,6 @@ int replica_check_for_data_reload (Replica *r, void *arg) + + ruv_force_csn_update_from_ruv(upper_bound_ruv, r_ruv, + "Force update of database RUV (from CL RUV) -> ", SLAPI_LOG_NOTICE); +- replica_set_ruv_dirty(r); + } + + } else { +@@ -2994,12 +2984,6 @@ replica_write_ruv (Replica *r) + + replica_lock(r->repl_lock); + +- if (!r->repl_ruv_dirty) +- { +- replica_unlock(r->repl_lock); +- return rc; +- } +- + PR_ASSERT (r->repl_ruv); + + ruv_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod); +@@ -3034,19 +3018,13 @@ replica_write_ruv (Replica *r) + /* ruv does not exist - create one */ + replica_lock(r->repl_lock); + +- if (rc == LDAP_SUCCESS) +- { +- r->repl_ruv_dirty = PR_FALSE; +- } +- else if (rc == LDAP_NO_SUCH_OBJECT) ++ if (rc == LDAP_NO_SUCH_OBJECT) + { + /* this includes an internal operation - but since this only happens + during server startup - its ok that we have lock around it */ + rc = _replica_configure_ruv (r, PR_TRUE); +- if (rc == 0) +- r->repl_ruv_dirty = PR_FALSE; + } +- else /* error */ ++ else if (rc != LDAP_SUCCESS) /* error */ + { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_write_ruv - Failed to update RUV tombstone for %s; " +@@ -3570,7 +3548,6 @@ replica_create_ruv_tombstone(Replica *r) + + if (ruv_init_new(csnstr, r->repl_rid, purl, &ruv) == RUV_SUCCESS){ + r->repl_ruv = object_new((void*)ruv, (FNFree)ruv_destroy); +- r->repl_ruv_dirty = PR_TRUE; + return_value = LDAP_SUCCESS; + } else { + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_create_ruv_tombstone - " +@@ -3610,8 +3587,6 @@ replica_create_ruv_tombstone(Replica *r) + slapi_add_internal_pb(pb); + e = NULL; /* add consumes e, upon success or failure */ + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value); +- if (return_value == LDAP_SUCCESS) +- r->repl_ruv_dirty = PR_FALSE; + + done: + slapi_entry_free (e); +@@ -3930,7 +3905,6 @@ replica_strip_cleaned_rids(Replica *r) + ruv_get_cleaned_rids(ruv, rid); + while(rid[i] != 0){ + ruv_delete_replica(ruv, rid[i]); +- replica_set_ruv_dirty(r); + if (replica_write_ruv(r)) { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "replica_strip_cleaned_rids - Failed to write RUV\n"); +@@ -4052,15 +4026,6 @@ replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv) + } + } + +-void +-replica_set_ruv_dirty(Replica *r) +-{ +- PR_ASSERT(r); +- replica_lock(r->repl_lock); +- r->repl_ruv_dirty = PR_TRUE; +- replica_unlock(r->repl_lock); +-} +- + PRBool + replica_is_state_flag_set(Replica *r, PRInt32 flag) + { +diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c +index 814f1cac0..128c9423a 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_config.c ++++ b/ldap/servers/plugins/replication/repl5_replica_config.c +@@ -1034,7 +1034,6 @@ replica_config_change_type_and_id (Replica *r, const char *new_type, + replica_reset_csn_pl(r); + } + ruv_delete_replica(ruv, oldrid); +- replica_set_ruv_dirty(r); + cl5CleanRUV(oldrid); + replica_set_csn_assigned(r); + } +@@ -1454,7 +1453,6 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not + return LDAP_UNWILLING_TO_PERFORM; + } + rc = ruv_delete_replica(local_ruv, rid); +- replica_set_ruv_dirty(replica); + if (replica_write_ruv(replica)) { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task - Could not write RUV\n"); + } +-- +2.13.6 + diff --git a/SOURCES/0085-Ticket-49495-Fix-memory-management-is-vattr.patch b/SOURCES/0085-Ticket-49495-Fix-memory-management-is-vattr.patch new file mode 100644 index 0000000..77f8311 --- /dev/null +++ b/SOURCES/0085-Ticket-49495-Fix-memory-management-is-vattr.patch @@ -0,0 +1,293 @@ +From d1236b0d3917b024a252b4d6acf823a975182d3b Mon Sep 17 00:00:00 2001 +From: William Brown +Date: Mon, 11 Dec 2017 15:48:24 +0100 +Subject: [PATCH] Ticket 49495 - Fix memory management is vattr. + +Bug Description: During the fix for +https://pagure.io/389-ds-base/issue/49436 a issue was exposed +in how registration of attributes to cos work. With the change +to handle -> attr link, this exposed that cos treats each attribute +and template pair as a new type for the handle. As aresult, this +caused the sp_list to create a long linked list of M*N entries +for each attr - template value. Obviously, this is extremely +slow to traverse during a search! + +Fix Description: Undo part of the SLL next change and convert +to reference counting. The issue remains that there is a defect +in how cos handles attribute registration, but this can not be +resolved without a significant rearchitecture of the code +related to virtual attributes. + +https://pagure.io/389-ds-base/issue/49495 + +Author: wibrown + +Review by: tbordaz, lkrispen (Thanks!) + +Note: includes backport of incr and decr for rc +--- + ldap/servers/plugins/cos/cos_cache.c | 28 ++++------ + ldap/servers/slapd/slapi-plugin.h | 21 ++++++++ + ldap/servers/slapd/slapi_counter.c | 30 +++++++++++ + ldap/servers/slapd/vattr.c | 100 +++++++++++++++++++++-------------- + 4 files changed, 122 insertions(+), 57 deletions(-) + +diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c +index 0e93183d2..74261af87 100644 +--- a/ldap/servers/plugins/cos/cos_cache.c ++++ b/ldap/servers/plugins/cos/cos_cache.c +@@ -275,7 +275,7 @@ static Slapi_Mutex *start_lock; + static Slapi_Mutex *stop_lock; + static Slapi_CondVar *something_changed = NULL; + static Slapi_CondVar *start_cond = NULL; +- ++static vattr_sp_handle *vattr_handle = NULL; + + /* + cos_cache_init +@@ -313,6 +313,15 @@ int cos_cache_init(void) + goto out; + } + ++ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, ++ cos_cache_vattr_get, ++ cos_cache_vattr_compare, ++ cos_cache_vattr_types) != 0) { ++ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider\n"); ++ ret = -1; ++ goto out; ++ } ++ + /* grab the views interface */ + if (slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) { + /* lets be tolerant if views is disabled */ +@@ -872,22 +881,7 @@ cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) + dnVals[valIndex]->bv_val); + } + +- /* +- * Each SP_handle is associated to one and only one vattr. +- * We could consider making this a single function rather +- * than the double-call. +- */ +- +- vattr_sp_handle *vattr_handle = NULL; +- +- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle, +- cos_cache_vattr_get, +- cos_cache_vattr_compare, +- cos_cache_vattr_types) != 0) { +- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val); +- } else { +- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); +- } ++ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL); + + } /* if(attrType is cosAttribute) */ + +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 4084945f4..16aa1b711 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -8063,6 +8063,27 @@ int slapi_is_special_rdn(const char *rdn, int flag); + */ + void DS_Sleep(PRIntervalTime ticks); + ++/** ++ * Increment a 64bitintegral atomicly ++ * ++ * \param ptr - pointer to integral to increment ++ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, ++ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST ++ * \return - new value of ptr ++ */ ++uint64_t slapi_atomic_incr_64(uint64_t *ptr, int memorder); ++ ++/** ++ * Decrement a 64bitintegral atomicly ++ * ++ * \param ptr - pointer to integral to decrement ++ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE, ++ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST ++ * \return - new value of ptr ++ */ ++uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder); ++ ++ + #ifdef __cplusplus + } + #endif +diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c +index 9904fe964..59e5223ad 100644 +--- a/ldap/servers/slapd/slapi_counter.c ++++ b/ldap/servers/slapd/slapi_counter.c +@@ -269,3 +269,33 @@ uint64_t slapi_counter_get_value(Slapi_Counter *counter) + return value; + } + ++/* ++ * atomic increment functions (64bit) ++ */ ++uint64_t ++slapi_atomic_incr_64(uint64_t *ptr, int memorder) ++{ ++#ifdef ATOMIC_64BIT_OPERATIONS ++ return __atomic_add_fetch_8(ptr, 1, memorder); ++#else ++ PRInt32 *pr_ptr = (PRInt32 *)ptr; ++ return PR_AtomicIncrement(pr_ptr); ++#endif ++} ++ ++/* ++ * atomic decrement functions (64bit) ++ */ ++ ++uint64_t ++slapi_atomic_decr_64(uint64_t *ptr, int memorder) ++{ ++#ifdef ATOMIC_64BIT_OPERATIONS ++ return __atomic_sub_fetch_8(ptr, 1, memorder); ++#else ++ PRInt32 *pr_ptr = (PRInt32 *)ptr; ++ return PR_AtomicDecrement(pr_ptr); ++#endif ++} ++ ++ +diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c +index 84e01cd62..adf44b0b6 100644 +--- a/ldap/servers/slapd/vattr.c ++++ b/ldap/servers/slapd/vattr.c +@@ -1529,10 +1529,12 @@ struct _vattr_sp { + typedef struct _vattr_sp vattr_sp; + + /* Service provider handle */ +-struct _vattr_sp_handle { +- vattr_sp *sp; +- struct _vattr_sp_handle *next; /* So we can link them together in the map */ +- void *hint; /* Hint to the SP */ ++struct _vattr_sp_handle ++{ ++ vattr_sp *sp; ++ struct _vattr_sp_handle *next; /* So we can link them together in the map */ ++ void *hint; /* Hint to the SP */ ++ uint64_t rc; + }; + + /* Calls made by Service Providers */ +@@ -1758,7 +1760,7 @@ is a separate thing in the insterests of stability. + + */ + +-#define VARRT_MAP_HASHTABLE_SIZE 10 ++#define VARRT_MAP_HASHTABLE_SIZE 32 + + /* Attribute map oject */ + /* Needs to contain: a linked list of pointers to provider handles handles, +@@ -1849,7 +1851,10 @@ vattr_map_entry_free(vattr_map_entry *vae) + vattr_sp_handle *list_entry = vae->sp_list; + while (list_entry != NULL) { + vattr_sp_handle *next_entry = list_entry->next; +- slapi_ch_free((void **)&list_entry); ++ if (slapi_atomic_decr_64(&(list_entry->rc), __ATOMIC_RELAXED) == 0) { ++ /* Only free on RC 0 */ ++ slapi_ch_free((void **)&list_entry); ++ } + list_entry = next_entry; + } + slapi_ch_free_string(&(vae->type_name)); +@@ -2268,41 +2273,56 @@ to handle the calls on it, but return nothing */ + * + * Better idea, is that regattr should just take the fn pointers + * and callers never *see* the sp_handle structure at all. ++ * ++ * This leaves us with some quirks today. First: if you have plugin A ++ * and B, A registers attr 1 and B 1 and 2, it's possible that if you ++ * register A1 first, then B1, you have B->A in next. Then when you ++ * register B2, because we take 0==result from map_lookup, we add sp ++ * "as is" to the map. This means that B2 now has the same next to A1 ++ * handle. This won't add a bug, because A1 won't be able to service the ++ * attr, but it could cause some head scratching ... ++ * ++ * Again, to fix this, the whole vattr external interface needs a ++ * redesign ... :( + */ +- +-int vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint) +-{ +- int result = 0; +- vattr_map_entry *map_entry = NULL; +- /* Is this type already there ? */ +- result = vattr_map_lookup(type_to_add,&map_entry); +- /* If it is, add this SP to the list, safely even if readers are traversing the list at the same time */ +- if (0 == result) { +- int found = 0; +- vattr_sp_handle *list_entry = NULL; +- /* Walk the list checking that the daft SP isn't already here */ +- for (list_entry = map_entry->sp_list ; list_entry; list_entry = list_entry->next) { +- if (list_entry == sp) { +- found = 1; +- break; +- } +- } +- /* If it is, we do nothing */ +- if(found) { +- return 0; +- } +- /* We insert the SP handle into the linked list at the head */ +- sp->next = map_entry->sp_list; +- map_entry->sp_list = sp; +- } else { +- /* If not, add it */ +- map_entry = vattr_map_entry_new(type_to_add,sp,hint); +- if (NULL == map_entry) { +- return ENOMEM; +- } +- return vattr_map_insert(map_entry); +- } +- return 0; ++int ++vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint) ++{ ++ int result = 0; ++ vattr_map_entry *map_entry = NULL; ++ /* Is this type already there ? */ ++ result = vattr_map_lookup(type_to_add, &map_entry); ++ /* If it is, add this SP to the list, safely even if readers are traversing the list at the same time */ ++ if (0 == result) { ++ int found = 0; ++ vattr_sp_handle *list_entry = NULL; ++ /* Walk the list checking that the daft SP isn't already here */ ++ for (list_entry = map_entry->sp_list; list_entry; list_entry = list_entry->next) { ++ if (list_entry == sp) { ++ found = 1; ++ break; ++ } ++ } ++ /* If it is, we do nothing */ ++ if (found) { ++ return 0; ++ } ++ /* Increase the ref count of the sphandle */ ++ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED); ++ /* We insert the SP handle into the linked list at the head */ ++ sp->next = map_entry->sp_list; ++ map_entry->sp_list = sp; ++ } else { ++ /* If not, add it */ ++ /* Claim a reference on the sp ... */ ++ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED); ++ map_entry = vattr_map_entry_new(type_to_add, sp, hint); ++ if (NULL == map_entry) { ++ return ENOMEM; ++ } ++ return vattr_map_insert(map_entry); ++ } ++ return 0; + } + + /* +-- +2.13.6 + diff --git a/SOURCES/0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch b/SOURCES/0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch new file mode 100644 index 0000000..23d764e --- /dev/null +++ b/SOURCES/0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch @@ -0,0 +1,117 @@ +From 040c492b4beb0efcd34b8420f682187441767055 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 16 Jan 2018 09:46:49 -0500 +Subject: [PATCH] CVE-2017-15134 389-ds-base: Remote DoS via search filters in + slapi_filter_sprintf + +Description: Improper handling of a search filter in slapi_filter_sprintf + in slapd/util.c can lead to remote server crash and denial + of service. + +https://bugzilla.redhat.com/show_bug.cgi?id=1529117 +--- + ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++----- + 1 file changed, 31 insertions(+), 5 deletions(-) + +diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c +index 4ff6d4141..ffeeff6f3 100644 +--- a/ldap/servers/slapd/util.c ++++ b/ldap/servers/slapd/util.c +@@ -224,9 +224,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ]) + + struct filter_ctx { + char *buf; +- char attr[ATTRSIZE]; ++ char *attr; + int attr_position; + int attr_found; ++ size_t attr_size; + int buf_size; + int buf_len; + int next_arg_needs_esc_norm; +@@ -265,7 +266,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) + * Start collecting the attribute name so we can use the correct + * syntax normalization func. + */ +- if(ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)){ ++ if(ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) { + if(ctx->attr[0] == '\0'){ + if(strstr(val,"=")){ + /* we have an attr we need to record */ +@@ -279,6 +280,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) + * attr with val. The next pass should be '=', otherwise we will + * reset it. + */ ++ if (slen > ctx->attr_size) { ++ if (ctx->attr_size == ATTRSIZE) { ++ ctx->attr = slapi_ch_calloc(sizeof(char), slen+1); ++ } else { ++ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1)); ++ } ++ ctx->attr_size = slen+1; ++ } + memcpy(ctx->attr, val, slen); + ctx->attr_position = slen; + } +@@ -288,9 +297,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) + } else { + if(special_attr_char(val[0])){ + /* this is not an attribute, we should not be collecting this, reset everything */ +- memset(ctx->attr, '\0', ATTRSIZE); ++ memset(ctx->attr, '\0', ctx->attr_size); + ctx->attr_position = 0; + } else { ++ /* we can be adding char by char and overrun allocated size */ ++ if (ctx->attr_position >= ctx->attr_size) { ++ if (ctx->attr_size == ATTRSIZE) { ++ char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE); ++ memcpy(ctxattr, ctx->attr, ctx->attr_size); ++ ctx->attr = ctxattr; ++ } else { ++ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE)); ++ } ++ ctx->attr_size = ctx->attr_size + ATTRSIZE; ++ } + memcpy(ctx->attr + ctx->attr_position, val, 1); + ctx->attr_position++; + } +@@ -363,7 +383,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen) + ctx->next_arg_needs_esc_norm = 0; + ctx->attr_found = 0; + ctx->attr_position = 0; +- memset(ctx->attr, '\0', ATTRSIZE); ++ memset(ctx->attr, '\0', ctx->attr_size); + slapi_ch_free_string(&buf); + + return filter_len; +@@ -402,13 +422,15 @@ slapi_filter_sprintf(const char *fmt, ...) + { + struct filter_ctx ctx = {0}; + va_list args; ++ char attr_static[ATTRSIZE] = {0}; + char *buf; + int rc; + + buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1); + ctx.buf = buf; +- memset(ctx.attr,'\0', ATTRSIZE); + ctx.attr_position = 0; ++ ctx.attr = attr_static; ++ ctx.attr_size = ATTRSIZE; + ctx.attr_found = 0; + ctx.buf_len = FILTER_BUF; + ctx.buf_size = 0; +@@ -424,6 +446,10 @@ slapi_filter_sprintf(const char *fmt, ...) + } + va_end(args); + ++ if (ctx.attr_size > ATTRSIZE) { ++ slapi_ch_free_string(&ctx.attr); ++ } ++ + return ctx.buf; + } + +-- +2.13.6 + diff --git a/SOURCES/0087-Ticket-49509-Indexing-of-internationalized-matching-.patch b/SOURCES/0087-Ticket-49509-Indexing-of-internationalized-matching-.patch new file mode 100644 index 0000000..e75f258 --- /dev/null +++ b/SOURCES/0087-Ticket-49509-Indexing-of-internationalized-matching-.patch @@ -0,0 +1,263 @@ +From 41a037c8310d204d21e9c3161d2015dd5177cff6 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 19 Dec 2017 11:53:13 +0100 +Subject: [PATCH] Ticket 49509 - Indexing of internationalized matching rules + is failing + +Bug Description: + Indexing of the internationalized matching rules tests if a + matching rule indexer handle or not a given OID. + A side effect of https://pagure.io/389-ds-base/issue/49097 is that + the returned indexing callbacks are lost. + Indeed, the indexing callbacks (and potentially others fields) were + stored in the temporary pblock that was memcpy to the provided + pblock in case of success + +Fix Description: + The fix basically restores the previous behavior but do not + memcpy pblock. It read/store the pblock fields that are + inputs/outputs of slapi_mr_indexer_create. + +https://pagure.io/389-ds-base/issue/49509 + +Reviewed by: Ludwig Krispenz + +Platforms tested: F23 + +Flag Day: no + +Doc impact: no +--- + ldap/servers/slapd/plugin_mr.c | 202 ++++++++++++++++++++++++++++++----------- + 1 file changed, 148 insertions(+), 54 deletions(-) + +diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c +index d216d12b9..b3cd4adf0 100644 +--- a/ldap/servers/slapd/plugin_mr.c ++++ b/ldap/servers/slapd/plugin_mr.c +@@ -145,6 +145,82 @@ plugin_mr_bind (char* oid, struct slapdplugin* plugin) + slapi_log_err(SLAPI_LOG_FILTER, "plugin_mr_bind", "<=\n"); + } + ++void ++mr_indexer_init_pb(Slapi_PBlock* src_pb, Slapi_PBlock* dst_pb) ++{ ++ char* oid; ++ char *type; ++ uint32_t usage; ++ void *object; ++ IFP destroyFn; ++ IFP indexFn, indexSvFn; ++ ++ /* matching rule plugin arguments */ ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_OID, &oid); ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_TYPE, &type); ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_USAGE, &usage); ++ ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_OID, oid); ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_TYPE, type); ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_USAGE, &usage); ++ ++ /* matching rule plugin functions */ ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); ++ ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn); ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn); ++ ++ /* common */ ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_OBJECT, &object); ++ slapi_pblock_get(src_pb, SLAPI_PLUGIN_DESTROY_FN, &destroyFn); ++ ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_OBJECT, object); ++ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_DESTROY_FN, destroyFn); ++ ++ ++} ++ ++/* ++ * Retrieves the matching rule plugin able to index/sort the provided OID/type ++ * ++ * The Matching rules able to index/sort a given OID are stored in a global list: global_mr_oids ++ * ++ * The retrieval is done in 3 phases: ++ * - It first searches (in global_mr_oids) for the already bound OID->MR ++ * - Else, look first in old style MR plugin ++ * for each registered 'syntax' and 'matchingrule' plugins having a ++ * SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, it binds (plugin_mr_bind) the first ++ * plugin that support the OID ++ * - Else, look in new style MR plugin ++ * for each registered 'syntax' and 'matchingrule' plugins, it binds (plugin_mr_bind) the first ++ * plugin that contains OID in its plg_mr_names ++ * ++ * Inputs: ++ * SLAPI_PLUGIN_MR_OID ++ * should contain the OID of the matching rule that you want used for indexing or sorting. ++ * SLAPI_PLUGIN_MR_TYPE ++ * should contain the attribute type that you want used for indexing or sorting. ++ * SLAPI_PLUGIN_MR_USAGE ++ * should specify if the indexer will be used for indexing (SLAPI_PLUGIN_MR_USAGE_INDEX) ++ * or for sorting (SLAPI_PLUGIN_MR_USAGE_SORT) ++ * ++ * ++ * Output: ++ * ++ * SLAPI_PLUGIN_MR_OID ++ * contain the OFFICIAL OID of the matching rule that you want used for indexing or sorting. ++ * SLAPI_PLUGIN_MR_INDEX_FN ++ * specifies the indexer function responsible for indexing or sorting of struct berval ** ++ * SLAPI_PLUGIN_MR_INDEX_SV_FN ++ * specifies the indexer function responsible for indexing or sorting of Slapi_Value ** ++ * SLAPI_PLUGIN_OBJECT ++ * contain any information that you want passed to the indexer function. ++ * SLAPI_PLUGIN_DESTROY_FN ++ * specifies the function responsible for freeing any memory allocated by this indexer factory function. ++ * For example, memory allocated for a structure that you pass to the indexer function using SLAPI_PLUGIN_OBJECT. ++ * ++ */ + int /* an LDAP error code, hopefully LDAP_SUCCESS */ + slapi_mr_indexer_create (Slapi_PBlock* opb) + { +@@ -152,60 +228,73 @@ slapi_mr_indexer_create (Slapi_PBlock* opb) + char* oid; + if (!(rc = slapi_pblock_get (opb, SLAPI_PLUGIN_MR_OID, &oid))) + { +- IFP createFn = NULL; +- struct slapdplugin* mrp = plugin_mr_find_registered (oid); +- if (mrp != NULL) +- { +- if (!(rc = slapi_pblock_set (opb, SLAPI_PLUGIN, mrp)) && +- !(rc = slapi_pblock_get (opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) && +- createFn != NULL) +- { +- rc = createFn (opb); +- } +- } +- else +- { +- /* call each plugin, until one is able to handle this request. */ +- rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; +- for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) +- { +- IFP indexFn = NULL; +- IFP indexSvFn = NULL; +- Slapi_PBlock pb; +- memcpy (&pb, opb, sizeof(Slapi_PBlock)); +- slapi_pblock_set(&pb, SLAPI_PLUGIN, mrp); +- if (slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) { +- /* plugin not a matchingrule type */ +- continue; +- } +- if (createFn && !createFn(&pb)) { +- slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); +- slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); +- if (indexFn || indexSvFn) { +- /* Success: this plugin can handle it. */ +- memcpy(opb, &pb, sizeof (Slapi_PBlock)); +- plugin_mr_bind(oid, mrp); /* for future reference */ +- rc = 0; /* success */ +- break; +- } +- +- } +- } +- if (rc != 0) { +- /* look for a new syntax-style mr plugin */ +- struct slapdplugin *pi = plugin_mr_find(oid); +- if (pi) { +- Slapi_PBlock pb; +- memcpy (&pb, opb, sizeof(Slapi_PBlock)); +- slapi_pblock_set(&pb, SLAPI_PLUGIN, pi); +- rc = default_mr_indexer_create(&pb); +- if (!rc) { +- memcpy (opb, &pb, sizeof(Slapi_PBlock)); +- plugin_mr_bind (oid, pi); /* for future reference */ +- } +- } +- } +- } ++ IFP createFn = NULL; ++ struct slapdplugin* mrp = plugin_mr_find_registered(oid); ++ if (mrp != NULL) { ++ /* Great the matching OID -> MR plugin was already found, just reuse it */ ++ if (!(rc = slapi_pblock_set(opb, SLAPI_PLUGIN, mrp)) && ++ !(rc = slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) && ++ createFn != NULL) { ++ rc = createFn(opb); ++ } ++ } else { ++ /* We need to find in the MR plugins list, the MR plugin that will be able to handle OID ++ * ++ * It can be "old style" MR plugin (i.e. collation) that define indexer ++ * ++ * It can be "now style" MR plugin that contain OID string in 'plg_mr_names' ++ * (ie. ces, cis, bin...) where plg_mr_names is defined in 'mr_plugin_table' in each file ++ * ces.c, cis.c... ++ * New style MR plugin have NULL indexer create function but rather use a default indexer ++ */ ++ ++ /* Look for a old syntax-style mr plugin ++ * call each plugin, until one is able to handle this request. ++ */ ++ rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; ++ ++ for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) { ++ ++ Slapi_PBlock *pb = slapi_pblock_new(); ++ mr_indexer_init_pb(opb, pb); ++ slapi_pblock_set(pb, SLAPI_PLUGIN, mrp); ++ /* This is associated with the pb_plugin struct, so it comes with mrp */ ++ if (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) { ++ /* plugin not a matchingrule type */ ++ slapi_pblock_destroy(pb); ++ continue; ++ } ++ ++ if (createFn && !createFn(pb)) { ++ IFP indexFn = NULL; ++ IFP indexSvFn = NULL; ++ /* These however, are in the pblock direct, so we need to copy them. */ ++ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn); ++ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn); ++ if (indexFn || indexSvFn) { ++ /* Success: this plugin can handle it. */ ++ mr_indexer_init_pb(pb, opb); ++ plugin_mr_bind(oid, mrp); /* for future reference */ ++ rc = 0; /* success */ ++ slapi_pblock_destroy(pb); ++ break; ++ } ++ } ++ slapi_pblock_destroy(pb); ++ } ++ if (rc != 0) { ++ /* look for a new syntax-style mr plugin */ ++ struct slapdplugin *pi = plugin_mr_find(oid); ++ if (pi) { ++ slapi_pblock_set(opb, SLAPI_PLUGIN, pi); ++ rc = default_mr_indexer_create(opb); ++ if (!rc) { ++ plugin_mr_bind(oid, pi); /* for future reference */ ++ } ++ slapi_pblock_set(opb, SLAPI_PLUGIN, NULL); ++ } ++ } ++ } + } + return rc; + } +@@ -683,6 +772,11 @@ default_mr_indexer_create(Slapi_PBlock* pb) + slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn); + slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn); + slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy); ++ ++ /* Note the two following setting are in the slapdplugin struct SLAPI_PLUGIN ++ * so they are not really output of the function but will just ++ * be stored in the bound (OID <--> plugin) list (plugin_mr_find_registered/plugin_mr_bind) ++ */ + slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create); + slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create); + rc = 0; +-- +2.13.6 + diff --git a/SOURCES/0088-Ticket-bz1525628-1.3.6-backport-invalid-password-mig.patch b/SOURCES/0088-Ticket-bz1525628-1.3.6-backport-invalid-password-mig.patch new file mode 100644 index 0000000..b5b280c --- /dev/null +++ b/SOURCES/0088-Ticket-bz1525628-1.3.6-backport-invalid-password-mig.patch @@ -0,0 +1,292 @@ +From 4219c54d9706f5597e8186d4f983b30587c2762e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 13 Feb 2018 10:32:06 -0500 +Subject: [PATCH] Ticket bz1525628 1.3.6 backport - invalid password migration + causes unauth bind + +Bug Description: Slapi_ct_memcmp expects both inputs to be +at LEAST size n. If they are not, we only compared UP to n. + +Invalid migrations of passwords (IE {CRYPT}XX) would create +a pw which is just salt and no hash. ct_memcmp would then +only verify the salt bits and would allow the authentication. + +This relies on an administrative mistake both of allowing +password migration (nsslapd-allow-hashed-passwords) and then +subsequently migrating an INVALID password to the server. + +Fix Description: slapi_ct_memcmp now access n1, n2 size +and will FAIL if they are not the same, but will still compare +n bytes, where n is the "longest" memory, to the first byte +of the other to prevent length disclosure of the shorter +value (generally the mis-migrated password) + +https://bugzilla.redhat.com/show_bug.cgi?id=1525628 + +Author: wibrown +--- + ldap/servers/plugins/pwdstorage/clear_pwd.c | 4 +- + ldap/servers/plugins/pwdstorage/crypt_pwd.c | 4 +- + ldap/servers/plugins/pwdstorage/md5_pwd.c | 14 +++---- + ldap/servers/plugins/pwdstorage/sha_pwd.c | 18 +++++++-- + ldap/servers/plugins/pwdstorage/smd5_pwd.c | 60 +++++++++++++++-------------- + ldap/servers/slapd/ch_malloc.c | 37 +++++++++++++++--- + ldap/servers/slapd/slapi-plugin.h | 2 +- + 7 files changed, 88 insertions(+), 51 deletions(-) + +diff --git a/ldap/servers/plugins/pwdstorage/clear_pwd.c b/ldap/servers/plugins/pwdstorage/clear_pwd.c +index b9b362d34..050e60dd7 100644 +--- a/ldap/servers/plugins/pwdstorage/clear_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/clear_pwd.c +@@ -39,7 +39,7 @@ clear_pw_cmp( const char *userpwd, const char *dbpwd ) + * However, even if the first part of userpw matches dbpwd, but len !=, we + * have already failed anyawy. This prevents substring matching. + */ +- if (slapi_ct_memcmp(userpwd, dbpwd, len_dbp) != 0) { ++ if (slapi_ct_memcmp(userpwd, dbpwd, len_user, len_dbp) != 0) { + result = 1; + } + } else { +@@ -51,7 +51,7 @@ clear_pw_cmp( const char *userpwd, const char *dbpwd ) + * dbpwd to itself. We have already got result == 1 if we are here, so we are + * just trying to take up time! + */ +- if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp)) { ++ if (slapi_ct_memcmp(dbpwd, dbpwd, len_dbp, len_dbp)) { + /* Do nothing, we have the if to fix a coverity check. */ + } + } +diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c +index dfd5af94b..ff8eabb07 100644 +--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c +@@ -56,13 +56,13 @@ crypt_close(Slapi_PBlock *pb __attribute__((unused))) + int + crypt_pw_cmp( const char *userpwd, const char *dbpwd ) + { +- int rc; ++ int32_t rc; + char *cp; + PR_Lock(cryptlock); + /* we use salt (first 2 chars) of encoded password in call to crypt() */ + cp = crypt( userpwd, dbpwd ); + if (cp) { +- rc= slapi_ct_memcmp( dbpwd, cp, strlen(dbpwd)); ++ rc= slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd), strlen(cp)); + } else { + rc = -1; + } +diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c +index b27994667..88c11688b 100644 +--- a/ldap/servers/plugins/pwdstorage/md5_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c +@@ -30,12 +30,12 @@ + int + md5_pw_cmp( const char *userpwd, const char *dbpwd ) + { +- int rc=-1; +- char * bver; +- PK11Context *ctx=NULL; ++ int32_t rc=-1; ++ char *bver; ++ PK11Context *ctx = NULL; + unsigned int outLen; + unsigned char hash_out[MD5_HASH_LEN]; +- unsigned char b2a_out[MD5_HASH_LEN*2]; /* conservative */ ++ unsigned char b2a_out[MD5_HASH_LEN * 2]; /* conservative */ + SECItem binary_item; + + ctx = PK11_CreateDigestContext(SEC_OID_MD5); +@@ -57,10 +57,10 @@ md5_pw_cmp( const char *userpwd, const char *dbpwd ) + bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item); + /* bver points to b2a_out upon success */ + if (bver) { +- rc = slapi_ct_memcmp(bver,dbpwd, strlen(dbpwd)); ++ rc = slapi_ct_memcmp(bver,dbpwd, strlen(dbpwd), strlen(bver)); + } else { +- slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME, +- "Could not base64 encode hashed value for password compare"); ++ slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME, ++ "Could not base64 encode hashed value for password compare"); + } + loser: + return rc; +diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c +index 5f41c5b93..c9db8964a 100644 +--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c +@@ -49,7 +49,7 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen ) + char userhash[MAX_SHA_HASH_SIZE]; + char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3]; + char *dbhash = quick_dbhash; +- struct berval salt; ++ struct berval salt = {0}; + PRUint32 hash_len; + unsigned int secOID; + char *schemeName; +@@ -120,10 +120,20 @@ sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen ) + } + + /* the proof is in the comparison... */ +- if ( hash_len >= shaLen ) { +- result = slapi_ct_memcmp( userhash, dbhash, shaLen ); ++ if (hash_len >= shaLen) { ++ /* ++ * This say "if the hash has a salt IE >, OR if they are equal, check the hash component ONLY. ++ * This is why we repeat shaLen twice, even though it seems odd. If you have a dbhast of ssha ++ * it's len is 28, and the userpw is 20, but 0 - 20 is the sha, and 21-28 is the salt, which ++ * has already been processed into userhash. ++ * The case where dbpwd is truncated is handled above in "invalid base64" arm. ++ */ ++ result = slapi_ct_memcmp(userhash, dbhash, shaLen, shaLen); + } else { +- result = slapi_ct_memcmp( userhash, dbhash + OLD_SALT_LENGTH, hash_len - OLD_SALT_LENGTH ); ++ /* This case is for if the salt is at the START, which only applies to DS40B1 case. ++ * May never be a valid check... ++ */ ++ result = slapi_ct_memcmp(userhash, dbhash + OLD_SALT_LENGTH, shaLen, hash_len - OLD_SALT_LENGTH); + } + + loser: +diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c +index 2e9d195ea..f6b4bb4a0 100644 +--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c +@@ -52,35 +52,37 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd ) + /* + * Decode hash stored in database. + */ +- hash_len = pwdstorage_base64_decode_len(dbpwd, 0); +- if ( hash_len >= sizeof(quick_dbhash) ) { /* get more space: */ +- dbhash = (char*) slapi_ch_calloc( hash_len + 1, sizeof(char) ); +- if ( dbhash == NULL ) goto loser; +- } else { +- memset( quick_dbhash, 0, sizeof(quick_dbhash) ); +- } +- +- hashresult = PL_Base64Decode( dbpwd, 0, dbhash ); +- if (NULL == hashresult) { +- slapi_log_err(SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME, +- "smd5_pw_cmp: userPassword \"%s\" is the wrong length " +- "or is not properly encoded BASE64\n", dbpwd ); +- goto loser; +- } +- +- salt.bv_val = (void*)(dbhash + MD5_LENGTH); /* salt starts after hash value */ +- salt.bv_len = hash_len - MD5_LENGTH; /* remaining bytes must be salt */ +- +- /* create the hash */ +- memset( userhash, 0, sizeof(userhash) ); +- PK11_DigestBegin(ctx); +- PK11_DigestOp(ctx, (const unsigned char *)userpwd, strlen(userpwd)); +- PK11_DigestOp(ctx, (unsigned char*)(salt.bv_val), salt.bv_len); +- PK11_DigestFinal(ctx, userhash, &outLen, sizeof userhash); +- PK11_DestroyContext(ctx, 1); +- +- /* Compare everything up to the salt. */ +- rc = slapi_ct_memcmp( userhash, dbhash, MD5_LENGTH ); ++ hash_len = pwdstorage_base64_decode_len(dbpwd, 0); ++ if (hash_len >= sizeof(quick_dbhash)) { /* get more space: */ ++ dbhash = (char *)slapi_ch_calloc(hash_len + 1, sizeof(char)); ++ if (dbhash == NULL) ++ goto loser; ++ } else { ++ memset(quick_dbhash, 0, sizeof(quick_dbhash)); ++ } ++ ++ hashresult = PL_Base64Decode(dbpwd, 0, dbhash); ++ if (NULL == hashresult) { ++ slapi_log_err(SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME, ++ "smd5_pw_cmp: userPassword \"%s\" is the wrong length " ++ "or is not properly encoded BASE64\n", ++ dbpwd); ++ goto loser; ++ } ++ ++ salt.bv_val = (void *)(dbhash + MD5_LENGTH); /* salt starts after hash value */ ++ salt.bv_len = hash_len - MD5_LENGTH; /* remaining bytes must be salt */ ++ ++ /* create the hash */ ++ memset(userhash, 0, sizeof(userhash)); ++ PK11_DigestBegin(ctx); ++ PK11_DigestOp(ctx, (const unsigned char *)userpwd, strlen(userpwd)); ++ PK11_DigestOp(ctx, (unsigned char *)(salt.bv_val), salt.bv_len); ++ PK11_DigestFinal(ctx, userhash, &outLen, sizeof userhash); ++ PK11_DestroyContext(ctx, 1); ++ ++ /* Compare everything up to the salt. */ ++ rc = slapi_ct_memcmp(userhash, dbhash, MD5_LENGTH, MD5_LENGTH); + + loser: + if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free_string( (char **)&dbhash ); +diff --git a/ldap/servers/slapd/ch_malloc.c b/ldap/servers/slapd/ch_malloc.c +index 52ccb64e8..da0b5f6d8 100644 +--- a/ldap/servers/slapd/ch_malloc.c ++++ b/ldap/servers/slapd/ch_malloc.c +@@ -343,8 +343,8 @@ slapi_ch_smprintf(const char *fmt, ...) + + /* Constant time memcmp. Does not shortcircuit on failure! */ + /* This relies on p1 and p2 both being size at least n! */ +-int +-slapi_ct_memcmp( const void *p1, const void *p2, size_t n) ++int32_t ++slapi_ct_memcmp( const void *p1, const void *p2, size_t n1, size_t n2) + { + int result = 0; + const unsigned char *_p1 = (const unsigned char *)p1; +@@ -353,10 +353,35 @@ slapi_ct_memcmp( const void *p1, const void *p2, size_t n) + if (_p1 == NULL || _p2 == NULL) { + return 2; + } +- +- for (size_t i = 0; i < n; i++) { +- if (_p1[i] ^ _p2[i]) { +- result = 1; ++ if (n1 == n2) { ++ for (size_t i = 0; i < n1; i++) { ++ if (_p1[i] ^ _p2[i]) { ++ result = 1; ++ } ++ } ++ } else { ++ const unsigned char *_pa; ++ const unsigned char *_pb; ++ size_t nl; ++ if (n2 > n1) { ++ _pa = _p2; ++ _pb = _p2; ++ nl = n2; ++ } else { ++ _pa = _p1; ++ _pb = _p1; ++ nl = n1; ++ } ++ /* We already fail as n1 != n2 */ ++ result = 3; ++ for (size_t i = 0; i < nl; i++) { ++ if (_pa[i] ^ _pb[i]) { ++ /* ++ * If we don't mutate result here, dead code elimination ++ * we remove for loop. ++ */ ++ result = 4; ++ } + } + } + return result; +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 16aa1b711..8555be939 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -5856,7 +5856,7 @@ char * slapi_ch_smprintf(const char *fmt, ...) + * \param n length in bytes of the content of p1 AND p2. + * \return 0 on match. 1 on non-match. 2 on presence of NULL pointer in p1 or p2. + */ +-int slapi_ct_memcmp( const void *p1, const void *p2, size_t n); ++int32_t slapi_ct_memcmp( const void *p1, const void *p2, size_t n1, size_t n2); + + /* + * syntax plugin routines +-- +2.13.6 + diff --git a/SOURCES/0089-Ticket-49545-final-substring-extended-filter-search-.patch b/SOURCES/0089-Ticket-49545-final-substring-extended-filter-search-.patch new file mode 100644 index 0000000..02cce65 --- /dev/null +++ b/SOURCES/0089-Ticket-49545-final-substring-extended-filter-search-.patch @@ -0,0 +1,66 @@ +From 73dd295434a03be28531cea40fde041ce7bd2d7e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 13 Feb 2018 10:35:35 -0500 +Subject: [PATCH] Ticket 49545 - final substring extended filter search returns + invalid result + +Bug Description: + During a search (using extended filter with final substring), the server + checks the filter before returning the matching entries. + When checking the attribute value against the filter, it + uses the wrong value. + +Fix Description: + Make suree it uses the right portion of the attribute value, in order + to generate the keys to compare. + +https://pagure.io/389-ds-base/issue/49545 + +Reviewed by: Ludwig Krispenz +--- + ldap/servers/plugins/collation/orfilter.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c +index 866936afe..8f10f81b6 100644 +--- a/ldap/servers/plugins/collation/orfilter.c ++++ b/ldap/servers/plugins/collation/orfilter.c +@@ -180,17 +180,33 @@ ss_filter_match (or_filter_t* or, struct berval** vals) + } else { /* final */ + auto size_t attempts = MAX_CHAR_COMBINING; + auto char* limit = v.bv_val; ++ auto char *end; + auto struct berval** vkeys; + auto struct berval* vals[2]; + auto struct berval key; ++ + rc = -1; + vals[0] = &v; + vals[1] = NULL; + key.bv_val = (*k)->bv_val; + key.bv_len = (*k)->bv_len - 1; +- v.bv_val = (*vals)->bv_val + (*vals)->bv_len; ++ /* In the following lines it will loop to find ++ * if the end of the attribute value matches the 'final' of the filter ++ * Short summary: ++ * vals contains the attribute value :for example "hello world" ++ * key contain the key generated from the indexing of final part of the filter. ++ * for example filter=(=*ld), so key contains the indexing("ld"). ++ * ++ * The loop will iterate over the attribute value (vals) from the end of string ++ * to the begining. So it will try to index('d'), index('ld'), index('rld'), index('orld')... ++ * ++ * At each iteration if the key generated from indexing the portion of vals, matches ++ * the key generate from the final part of the filter, then the loop stops => we are done ++ */ ++ end = v.bv_val + v.bv_len - 1; ++ v.bv_val = end; + while(1) { +- v.bv_len = (*vals)->bv_len - (v.bv_val - (*vals)->bv_val); ++ v.bv_len = end - v.bv_val + 1; + vkeys = ix->ix_index (ix, vals, NULL); + if (vkeys && vkeys[0]) { + auto const struct berval* vkey = vkeys[0]; +-- +2.13.6 + diff --git a/SOURCES/0090-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch b/SOURCES/0090-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch new file mode 100644 index 0000000..ca57d86 --- /dev/null +++ b/SOURCES/0090-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch @@ -0,0 +1,189 @@ +From 715bdd7fd707d4addf52c21051ec3ab90951a691 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Wed, 6 Dec 2017 15:14:57 +0100 +Subject: [PATCH] Ticket 49471 - heap-buffer-overflow in ss_unescape + +Bug Description: + Two problems here + - when searching for wildcard and escape char, ss_unescape assumes the string + is at least 3 chars longs. So memcmp can overflow a shorter string + - while splitting a string into substring pattern, it loops over + wildcard and can overpass the string end + +Fix Description: + For the first problem, it checks the string size is long enough to memcmp + a wildcard or an escape + For the second it exits from the loop as soon as the end of the string is reached + +https://pagure.io/389-ds-base/issue/49471 + +Reviewed by: William Brown + +Platforms tested: F23 + +Flag Day: no + +Doc impact: no + +(cherry picked from commit 5991388ce75fba8885579b769711d57acfd43cd3) +(cherry picked from commit 3fb1c408cb4065de8d9c0c1de050d08969d51bb0) +--- + dirsrvtests/tests/tickets/ticket49471_test.py | 79 +++++++++++++++++++++++++++ + ldap/servers/plugins/collation/orfilter.c | 48 +++++++++------- + 2 files changed, 106 insertions(+), 21 deletions(-) + create mode 100644 dirsrvtests/tests/tickets/ticket49471_test.py + +diff --git a/dirsrvtests/tests/tickets/ticket49471_test.py b/dirsrvtests/tests/tickets/ticket49471_test.py +new file mode 100644 +index 000000000..0456a5182 +--- /dev/null ++++ b/dirsrvtests/tests/tickets/ticket49471_test.py +@@ -0,0 +1,79 @@ ++import logging ++import pytest ++import os ++import time ++import ldap ++from lib389._constants import * ++from lib389.topologies import topology_st as topo ++from lib389 import Entry ++ ++DEBUGGING = os.getenv("DEBUGGING", default=False) ++if DEBUGGING: ++ logging.getLogger(__name__).setLevel(logging.DEBUG) ++else: ++ logging.getLogger(__name__).setLevel(logging.INFO) ++log = logging.getLogger(__name__) ++ ++ ++USER_CN='user_' ++def _user_get_dn(no): ++ cn = '%s%d' % (USER_CN, no) ++ dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX) ++ return (cn, dn) ++ ++def add_user(server, no, desc='dummy', sleep=True): ++ (cn, dn) = _user_get_dn(no) ++ log.fatal('Adding user (%s): ' % dn) ++ server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser', 'userSecurityInformation'], ++ 'cn': [cn], ++ 'description': [desc], ++ 'sn': [cn], ++ 'description': ['add on that host']}))) ++ if sleep: ++ time.sleep(2) ++ ++def test_ticket49471(topo): ++ """Specify a test case purpose or name here ++ ++ :id: 457ab172-9455-4eb2-89a0-150e3de5993f ++ :setup: Fill in set up configuration here ++ :steps: ++ 1. Fill in test case steps here ++ 2. And indent them like this (RST format requirement) ++ :expectedresults: ++ 1. Fill in the result that is expected ++ 2. For each test step ++ """ ++ ++ # If you need any test suite initialization, ++ # please, write additional fixture for that (including finalizer). ++ # Topology for suites are predefined in lib389/topologies.py. ++ ++ # If you need host, port or any other data about instance, ++ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid) ++ ++ S1 = topo.standalone ++ add_user(S1, 1) ++ ++ Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*on\*)" ++ ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter) ++ assert len(ents) == 1 ++ ++ # ++ # The following is for the test 49491 ++ # skipped here else it crashes in ASAN ++ #Filter = "(description:2.16.840.1.113730.3.3.2.1.1.6:=\*host)" ++ #ents = S1.search_s(SUFFIX, ldap.SCOPE_SUBTREE, Filter) ++ #assert len(ents) == 1 ++ ++ if DEBUGGING: ++ # Add debugging steps(if any)... ++ pass ++ ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main("-s %s" % CURRENT_FILE) ++ +diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c +index 8f10f81b6..438efafef 100644 +--- a/ldap/servers/plugins/collation/orfilter.c ++++ b/ldap/servers/plugins/collation/orfilter.c +@@ -317,19 +317,21 @@ ss_unescape (struct berval* val) + char* t = s; + char* limit = s + val->bv_len; + while (s < limit) { +- if (!memcmp (s, "\\2a", 3) || +- !memcmp (s, "\\2A", 3)) { +- *t++ = WILDCARD; +- s += 3; +- } else if (!memcmp (s, "\\5c", 3) || +- !memcmp (s, "\\5C", 3)) { +- *t++ = '\\'; +- s += 3; +- } else { +- if (t == s) LDAP_UTF8INC (t); +- else t += LDAP_UTF8COPY (t, s); +- LDAP_UTF8INC (s); +- } ++ if (((limit - s) >= 3) && ++ (!memcmp(s, "\\2a", 3) || !memcmp(s, "\\2A", 3))) { ++ *t++ = WILDCARD; ++ s += 3; ++ } else if ((limit - s) >= 3 && ++ (!memcmp(s, "\\5c", 3) || !memcmp(s, "\\5C", 3))) { ++ *t++ = '\\'; ++ s += 3; ++ } else { ++ if (t == s) ++ LDAP_UTF8INC(t); ++ else ++ t += LDAP_UTF8COPY(t, s); ++ LDAP_UTF8INC(s); ++ } + } + val->bv_len = t - val->bv_val; + } +@@ -405,14 +407,18 @@ ss_filter_values (struct berval* pattern, int* query_op) + n = 0; + s = pattern->bv_val; + for (p = s; p < plimit; LDAP_UTF8INC(p)) { +- switch (*p) { +- case WILDCARD: +- result[n++] = ss_filter_value (s, p-s, &val); +- while (++p != plimit && *p == WILDCARD); +- s = p; +- break; +- default: break; +- } ++ switch (*p) { ++ case WILDCARD: ++ result[n++] = ss_filter_value(s, p - s, &val); ++ while (p != plimit && *p == WILDCARD) p++; ++ s = p; ++ break; ++ default: ++ break; ++ } ++ if (p >= plimit) { ++ break; ++ } + } + if (p != s || s == plimit) { + result[n++] = ss_filter_value (s, p-s, &val); +-- +2.13.6 + diff --git a/SOURCES/0091-Ticket-49540-Indexing-task-is-reported-finished-too-.patch b/SOURCES/0091-Ticket-49540-Indexing-task-is-reported-finished-too-.patch new file mode 100644 index 0000000..3882b75 --- /dev/null +++ b/SOURCES/0091-Ticket-49540-Indexing-task-is-reported-finished-too-.patch @@ -0,0 +1,206 @@ +From b7b71e2da754f950229cbc34d55e34e1314de301 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Fri, 19 Jan 2018 17:50:59 +0100 +Subject: [PATCH] Ticket 49540 - Indexing task is reported finished too early + regarding the backend status + +Bug Description: + If a task complete successfully, its status is updated before the backend + can receive update. + +Fix Description: + postpone the task status update after backend is reenabled + +https://pagure.io/389-ds-base/issue/49540 + +Reviewed by: Ludwig Krispenz + +Platforms tested: F26 + +Flag Day: no + +Doc impact: no +--- + dirsrvtests/tests/tickets/ticket49540_test.py | 135 ++++++++++++++++++++++++++ + ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 16 +-- + 2 files changed, 145 insertions(+), 6 deletions(-) + create mode 100644 dirsrvtests/tests/tickets/ticket49540_test.py + +diff --git a/dirsrvtests/tests/tickets/ticket49540_test.py b/dirsrvtests/tests/tickets/ticket49540_test.py +new file mode 100644 +index 000000000..1fbfde2c5 +--- /dev/null ++++ b/dirsrvtests/tests/tickets/ticket49540_test.py +@@ -0,0 +1,135 @@ ++import logging ++import pytest ++import os ++import ldap ++import time ++import re ++from lib389._constants import * ++from lib389.tasks import * ++from lib389.topologies import topology_st as topo ++from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES ++from lib389 import Entry ++ ++ ++ ++DEBUGGING = os.getenv("DEBUGGING", default=False) ++if DEBUGGING: ++ logging.getLogger(__name__).setLevel(logging.DEBUG) ++else: ++ logging.getLogger(__name__).setLevel(logging.INFO) ++log = logging.getLogger(__name__) ++ ++HOMEDIRECTORY_INDEX = 'cn=homeDirectory,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config' ++HOMEDIRECTORY_CN = "homedirectory" ++MATCHINGRULE = 'nsMatchingRule' ++USER_CN = 'user_' ++ ++def create_index_entry(topo): ++ log.info("\n\nindex homeDirectory") ++ try: ++ ent = topo.getEntry(HOMEDIRECTORY_INDEX, ldap.SCOPE_BASE) ++ except ldap.NO_SUCH_OBJECT: ++ topo.add_s(Entry((HOMEDIRECTORY_INDEX, { ++ 'objectclass': "top nsIndex".split(), ++ 'cn': HOMEDIRECTORY_CN, ++ 'nsSystemIndex': 'false', ++ MATCHINGRULE: ['caseIgnoreIA5Match', 'caseExactIA5Match' ], ++ 'nsIndexType': ['eq', 'sub', 'pres']}))) ++ ++ ++def provision_users(topo): ++ test_users = [] ++ homeValue = b'x' * (32 * 1024) # just to slow down indexing ++ for i in range(100): ++ CN = '%s%d' % (USER_CN, i) ++ users = UserAccounts(topo, SUFFIX) ++ user_props = TEST_USER_PROPERTIES.copy() ++ user_props.update({'uid': CN, 'cn': CN, 'sn': '_%s' % CN, HOMEDIRECTORY_CN: homeValue}) ++ testuser = users.create(properties=user_props) ++ test_users.append(testuser) ++ return test_users ++ ++def start_start_status(server): ++ args = {TASK_WAIT: False} ++ indexTask = Tasks(server) ++ indexTask.reindex(suffix=SUFFIX, attrname='homeDirectory', args=args) ++ return indexTask ++ ++def check_task_status(server, indexTask, test_entry): ++ finish_pattern = re.compile(".*Finished indexing.*") ++ mod = [(ldap.MOD_REPLACE, 'sn', b'foo')] ++ for i in range(10): ++ log.info("check_task_status =========> %d th loop" % i) ++ try: ++ ent = server.getEntry(indexTask.dn, ldap.SCOPE_BASE) ++ if ent.hasAttr('nsTaskStatus'): ++ value = str(ent.getValue('nsTaskStatus')) ++ finish = finish_pattern.search(value) ++ log.info("%s ---> %s" % (indexTask.dn, value)) ++ else: ++ finish = None ++ log.info("%s ---> NO STATUS" % (indexTask.dn)) ++ ++ if not finish: ++ # This is not yet finished try an update ++ try: ++ server.modify_s(test_entry, mod) ++ ++ # weird, may be indexing just complete ++ ent = server.getEntry(indexTask.dn, ldap.SCOPE_BASE, ['nsTaskStatus']) ++ assert (ent.hasAttr('nsTaskStatus') and regex.search(ent.getValue('nsTaskStatus'))) ++ log.info("Okay, it just finished so the MOD was successful") ++ except ldap.UNWILLING_TO_PERFORM: ++ log.info("=========> Great it was expected in the middle of index") ++ else: ++ # The update should be successful ++ server.modify_s(test_entry, mod) ++ ++ except ldap.NO_SUCH_OBJECT: ++ log.info("%s: no found" % (indexTask.dn)) ++ ++ time.sleep(1) ++ ++def test_ticket49540(topo): ++ """Specify a test case purpose or name here ++ ++ :id: 1df16d5a-1b92-46b7-8435-876b87545748 ++ :setup: Standalone Instance ++ :steps: ++ 1. Create homeDirectory index (especially with substring) ++ 2. Creates 100 users with large homeDirectory value => long to index ++ 3. Start an indexing task WITHOUT waiting for its completion ++ 4. Monitor that until task.status = 'Finish', any update -> UNWILLING to perform ++ :expectedresults: ++ 1. Index configuration succeeds ++ 2. users entry are successfully created ++ 3. Indexing task is started ++ 4. If the task.status does not contain 'Finished indexing', any update should return UNWILLING_TO_PERFORM ++ When it contains 'Finished indexing', updates should be successful ++ """ ++ ++ server = topo.standalone ++ create_index_entry(server) ++ test_users = provision_users(server) ++ ++ indexTask = start_start_status(server) ++ check_task_status(server, indexTask, test_users[0].dn) ++ ++ # If you need any test suite initialization, ++ # please, write additional fixture for that (including finalizer). ++ # Topology for suites are predefined in lib389/topologies.py. ++ ++ # If you need host, port or any other data about instance, ++ # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid) ++ ++ if DEBUGGING: ++ # Add debugging steps(if any)... ++ pass ++ ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main(["-s", CURRENT_FILE]) ++ +diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +index 6d897edc7..6527a477c 100644 +--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c ++++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +@@ -2533,12 +2533,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) + vlvIndex_go_online(pvlv[vlvidx], be); + } + +- if (task) { +- slapi_task_log_status(task, "%s: Finished indexing.", +- inst->inst_name); +- slapi_task_log_notice(task, "%s: Finished indexing.", +- inst->inst_name); +- } ++ /* if it was a task, its status will be updated later after backend is ready for update */ + slapi_log_err(SLAPI_LOG_INFO, "ldbm_back_ldbm2index", "%s: Finished indexing.\n", + inst->inst_name); + return_value = 0; /* success */ +@@ -2562,6 +2557,15 @@ err_min: + dblayer_release_id2entry( be, db ); /* nope */ + instance_set_not_busy(inst); + ++ if (return_value == 0) { ++ if (task) { ++ slapi_task_log_status(task, "%s: Finished indexing.", ++ inst->inst_name); ++ slapi_task_log_notice(task, "%s: Finished indexing.", ++ inst->inst_name); ++ } ++ } ++ + if (run_from_cmdline) { + if (0 != dblayer_flush(li)) { + slapi_log_err(SLAPI_LOG_ERR, +-- +2.13.6 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index 83e3afc..5b0009a 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -9,22 +9,13 @@ # If perl-Socket-2.000 or newer is available, set 0 to use_Socket6. %global use_Socket6 0 +%global use_nunc_stans 1 - -# This is used in certain builds to help us know if it has extra features. -%global variant base -%global use_asan 0 - -%if %{use_asan} -%global use_tcmalloc 0 -%global variant base-asan -%else %if %{_arch} != "s390x" && %{_arch} != "s390" %global use_tcmalloc 1 %else %global use_tcmalloc 0 %endif -%endif # fedora 15 and later uses tmpfiles.d # otherwise, comment this out @@ -36,10 +27,10 @@ # set PIE flag %global _hardened_build 1 -Summary: 389 Directory Server (%{variant}) +Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.3.7.5 -Release: %{?relprefix}19%{?prerel}%{?dist} +Version: 1.3.6.1 +Release: %{?relprefix}29%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org/ Group: System Environment/Daemons @@ -49,7 +40,7 @@ Requires: %{name}-libs = %{version}-%{release} Provides: ldif2ldbm >= 0 BuildRequires: nspr-devel -BuildRequires: nss-devel >= 3.34 +BuildRequires: nss-devel BuildRequires: svrcore-devel >= 4.1.3 BuildRequires: openldap-devel BuildRequires: libdb-devel @@ -59,7 +50,6 @@ BuildRequires: libicu-devel BuildRequires: pcre-devel BuildRequires: gcc-c++ # The following are needed to build the snmp ldap-agent -BuildRequires: net-snmp BuildRequires: net-snmp-devel %ifnarch sparc sparc64 ppc ppc64 s390 s390x BuildRequires: lm_sensors-devel @@ -72,16 +62,15 @@ BuildRequires: tcp_wrappers BuildRequires: pam-devel BuildRequires: systemd-units BuildRequires: systemd-devel -%if %{use_asan} -BuildRequires: libasan -%endif # Needed to support regeneration of the autotool artifacts. BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool +%if %{use_nunc_stans} BuildRequires: libevent-devel BuildRequires: libtalloc-devel BuildRequires: libtevent-devel +%endif # For tests! #BuildRequires: libcmocka-devel BuildRequires: doxygen @@ -95,7 +84,6 @@ Requires: selinux-policy >= 3.13.1-137 # the following are needed for some of our scripts Requires: openldap-clients - # use_openldap assumes perl-Mozilla-LDAP is built with openldap support Requires: perl-Mozilla-LDAP @@ -132,7 +120,6 @@ Requires: perl-Socket Requires: perl-NetAddr-IP Requires: systemd-libs Requires: svrcore >= 4.1.3 -Requires: python-ldap # upgrade path from monolithic % {name} (including -libs & -devel) to % {name} + % {name}-snmp Obsoletes: %{name} <= 1.3.5.4 @@ -142,79 +129,102 @@ BuildRequires: gperftools-devel Requires: gperftools-libs %endif -Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 +Source0: http://www.port389.org/binaries/%{name}-%{version}%{?prerel}.tar.bz2 # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README -Patch00: 0000-Ticket-49305-Need-to-wrap-atomic-calls.patch -Patch01: 0001-Ticket-49305-Need-to-wrap-atomic-calls.patch -Patch02: 0002-Ticket-49385-Fix-coverity-warnings.patch -Patch03: 0003-Ticket-49180-errors-log-filled-with-attrlist_replace.patch -Patch04: 0004-Ticket-49388-repl-monitor-matches-null-string-many-t.patch -Patch05: 0005-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch -Patch06: 0006-Ticket-49320-Activating-already-active-role-returns-.patch -Patch07: 0007-Ticket-48235-Remove-memberOf-global-lock.patch -Patch08: 0008-Ticket-48235-remove-memberof-lock-cherry-pick-error.patch -Patch09: 0009-Ticket-49394-slapi_pblock_get-may-leave-unchanged-th.patch -Patch10: 0010-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch -Patch11: 0011-Ticket-49064-RFE-allow-to-enable-MemberOf-plugin-in-.patch -Patch12: 0012-Ticket-49378-server-init-fails.patch -Patch13: 0013-Ticket-49392-memavailable-not-available.patch -Patch14: 0014-Ticket-48006-Missing-warning-for-invalid-replica-bac.patch -Patch15: 0015-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch -Patch16: 0016-Ticket-49408-Server-allows-to-set-any-nsds5replicaid.patch -Patch17: 0017-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch -Patch18: 0018-Ticket-49374-server-fails-to-start-because-maxdisksi.patch -Patch19: 0019-Ticket-48681-Use-of-uninitialized-value-in-string-ne.patch -Patch20: 0020-Ticket-49401-improve-valueset-sorted-performance-on-.patch -Patch21: 0021-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch -Patch22: 0022-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch -Patch23: 0023-Ticket-49424-Resolve-csiphash-alignment-issues.patch -Patch24: 0024-Ticket-49436-double-free-in-COS-in-some-conditions.patch -Patch25: 0025-Ticket-48393-Improve-replication-config-validation.patch -Patch26: 0026-Ticket-49439-cleanallruv-is-not-logging-information.patch -Patch27: 0027-Ticket-48393-fix-copy-and-paste-error.patch -Patch28: 0028-Ticket-49038-remove-legacy-replication-change-cleanu.patch -Patch29: 0029-Ticket-49454-SSL-Client-Authentication-breaks-in-FIP.patch -Patch30: 0030-Ticket-49435-Fix-NS-race-condition-on-loaded-test-sy.patch -Patch31: 0031-Ticket-49410-opened-connection-can-remain-no-longer-.patch -Patch32: 0032-Ticket-49443-scope-one-searches-in-1.3.7-give-incorr.patch -Patch33: 0033-Ticket-49441-Import-crashes-with-large-indexed-binar.patch -Patch34: 0034-Ticket-49441-Import-crashes-oneline-fix.patch -Patch35: 0035-Ticket-49377-Incoming-BER-too-large-with-TLS-on-plai.patch -Patch36: 0036-Ticket-48118-At-startup-changelog-can-be-erronously-.patch -Patch37: 0037-Ticket-48118-fix-compiler-warning-for-incorrect-retu.patch -Patch38: 0038-Ticket-49298-Correct-error-codes-with-config-restore.patch -Patch39: 0039-Ticket-49474-sasl-allow-mechs-does-not-operate-corre.patch -Patch40: 0040-Ticket-49470-overflow-in-pblock_get.patch -Patch41: 0041-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch -Patch42: 0042-Ticket-49298-fix-complier-warn.patch -Patch43: 0043-Ticket-49495-Fix-memory-management-is-vattr.patch -# Patch44: 0044-Ticket-48184-close-connections-at-shutdown-cleanly.patch -Patch45: 0045-Ticket-49509-Indexing-of-internationalized-matching-.patch -Patch46: 0046-Ticket-49493-heap-use-after-free-in-csn_as_string.patch -Patch47: 0047-Ticket-49524-Password-policy-minimum-token-length-fa.patch -Patch48: 0048-Ticket-49446-cleanallruv-should-ignore-cleaned-repli.patch -Patch49: 0049-Ticket-49413-Changelog-trimming-ignores-disabled-rep.patch -Patch50: 0050-Ticket-49278-GetEffectiveRights-gives-false-negative.patch -Patch51: 0051-Ticket-49531-coverity-issues-fix-memory-leaks.patch -Patch52: 0052-Ticket-49529-Fix-Coverity-warnings-invalid-deference.patch -Patch53: 0053-Ticket-49463-After-cleanALLruv-there-is-a-flow-of-ke.patch -Patch54: 0054-Ticket-49532-coverity-issues-fix-compiler-warnings-c.patch -Patch55: 0055-Ticket-49523-memberof-schema-violation-error-message.patch -Patch56: 0056-Ticket-49534-Fix-coverity-issues-and-regression.patch -Patch57: 0057-Ticket-49370-Add-all-the-password-policy-defaults-to.patch -Patch58: 0058-Ticket-49541-repl-config-should-not-allow-rid-65535-.patch -Patch59: 0059-CVE-2017-15134-crash-in-slapi_filter_sprintf.patch -Patch60: 0060-Ticket-49534-Fix-coverity-regression.patch -Patch61: 0061-Ticket-49541-Replica-ID-config-validation-fix.patch -Patch62: 0062-Ticket-49370-Crash-when-using-a-global-and-local-pw.patch -Patch63: 0063-Ticket-49557-Add-config-option-for-checking-CRL-on-o.patch -Patch64: 0064-Ticket-49560-nsslapd-extract-pemfiles-should-be-enab.patch -Patch65: 0065-Ticket-bz1525628-invalid-password-migration-causes-u.patch -Patch66: 0066-Ticket-49545-final-substring-extended-filter-search-.patch -Patch67: 0067-Ticket-49551-v3-correct-handling-of-numsubordinates-.patch -Patch68: 0068-Ticket-49551-fix-memory-leak-found-by-coverity.patch +Patch0: 0000-Ticket-49164-Change-NS-to-acq-rel-semantics-for-atom.patch +Patch1: 0001-Issue-49170-sync-plugin-thread-count-not-handled-cor.patch +Patch2: 0002-Ticket-49165-pw_verify-did-not-handle-external-auth.patch +Patch3: 0003-Issue-49169-Fix-covscan-errors.patch +Patch4: 0004-Ticket-49171-Nunc-Stans-incorrectly-reports-a-timeou.patch +Patch5: 0005-Issue-49169-Fix-covscan-errors-regression.patch +Patch6: 0006-Issue-49062-Reset-agmt-update-staus-and-total-init +Patch7: 0007-Issue-49065-dbmon.sh-fails-if-you-have-nsslapd-requi.patch +Patch8: 0008-Issue-49095-targetattr-wildcard-evaluation-is-incorr.patch +Patch9: 0009-Issue-49157-ds-logpipe.py-crashes-for-non-existing-u.patch +Patch10: 0010-Fix-double-free-in-_cl5NewDBFile-error-path.patch +Patch11: 0011-Issue-49188-retrocl-can-crash-server-at-shutdown.patch +Patch12: 0012-Ticket-49177-rpm-would-not-create-valid-pkgconfig-fi.patch +Patch13: 0013-Ticket-49076-To-debug-DB_DEADLOCK-condition-allow-to.patch +Patch14: 0014-Issue-49192-Deleting-suffix-can-hang-server.patch +Patch15: 0015-Ticket-49174-nunc-stans-can-not-use-negative-timeout.patch +Patch16: 0016-Issue-48989-Integer-overflow.patch +Patch17: 0017-Issue-49035-dbmon.sh-shows-pages-in-use-that-exceeds.patch +Patch18: 0018-Issue-49177-Fix-pkg-config-file.patch +Patch19: 0019-Issue-49205-Fix-logconv.pl-man-page.patch +Patch20: 0020-Issue-49039-password-min-age-should-be-ignored-if-pa.patch +Patch21: 0021-fix-for-cve-2017-2668-simple-return-text-if-suffix-n.patch +Patch22: 0022-Issue-47662-CLI-args-get-removed.patch +Patch23: 0023-Issue-49210-Fix-regression-when-checking-is-password.patch +Patch24: 0024-Ticket-49209-Hang-due-to-omitted-replica-lock-releas.patch +Patch25: 0025-Ticket-49184-Overflow-in-memberof.patch +Patch26: 0026-Ticket-49196-Autotune-generates-crit-messages.patch +Patch27: 0027-Issue-49221-During-an-upgrade-the-provided-localhost.patch +Patch28: 0028-Ticket-48864-Add-cgroup-memory-limit-detection-to-38.patch +Patch29: 0029-Ticket-49204-Fix-lower-bounds-on-import-autosize-On-.patch +Patch30: 0030-Ticket-49231-fix-sasl-mech-handling.patch +Patch31: 0031-Ticket-49230-slapi_register_plugin-creates-config-en.patch +Patch32: 0032-49227-ldapsearch-for-nsslapd-errorlog-level-re.patch +Patch33: 0033-Ticket-48989-fix-perf-counters.patch +Patch34: 0034-Ticket-48681-logconv.pl-fix-sasl-bind-stats.patch +Patch35: 0035-Ticket-49241-Update-man-page-and-usage-for-db2bak.pl.patch +Patch36: 0036-Ticket-7662-db2index-not-properly-evalauating-argume.patch +Patch37: 0037-Ticket-49075-Adjust-logging-severity-levels.patch +Patch38: 0038-Ticket-49231-Fix-backport-issue.patch +Patch39: 0039-Ticket-49231-Fix-backport-issue-part2.patch +Patch40: 0040-Ticket-48681-logconv.pl-Fix-SASL-Bind-stats-and-rewo.patch +Patch41: 0041-Ticket-49157-ds-logpipe.py-crashes-for-non-existing-.patch +Patch42: 0042-Ticket-49249-cos_cache-is-erroneously-logging-schema.patch +Patch43: 0043-Ticket-49238-AddressSanitizer-heap-use-after-free-in.patch +Patch44: 0044-Ticket-49246-ns-slapd-crashes-in-role-cache-creation.patch +Patch45: 0045-Ticket-49258-Allow-nsslapd-cache-autosize-to-be-modi.patch +Patch46: 0046-Ticket-49261-Fix-script-usage-and-man-pages.patch +Patch47: 0047-Ticket-48864-Fix-FreeIPA-build.patch +Patch48: 0048-Ticket-49157-fix-error-in-ds-logpipe.py.patch +Patch49: 0049-Ticket-49267-autosize-split-of-0-results-in-dbcache-.patch +Patch50: 0050-Ticket-49231-force-EXTERNAL-always.patch +Patch51: 0051-Ticket-48538-Failed-to-delete-old-semaphore.patch +Patch52: 0052-Ticket-49257-Reject-nsslapd-cachememsize-nsslapd-cac.patch +Patch53: 0053-Ticket-49257-Reject-dbcachesize-updates-while-auto-c.patch +Patch54: 0054-Ticket-49184-adjust-logging-level-in-MO-plugin.patch +Patch55: 0055-Ticket-49241-add-symblic-link-location-to-db2bak.pl-.patch +Patch56: 0056-Ticket-49313-Change-the-retrochangelog-default-cache.patch +Patch57: 0057-Ticket-49287-v3-extend-csnpl-handling-to-multiple-ba.patch +Patch58: 0058-Ticket-49336-SECURITY-Locked-account-provides-differ.patch +Patch59: 0059-Ticket-49298-force-sync-on-shutdown.patch +Patch60: 0060-Ticket-49334-fix-backup-restore-if-changelog-exists.patch +Patch61: 0061-Ticket-49356-mapping-tree-crash-can-occur-during-tot.patch +Patch62: 0062-Ticket-49330-Improve-ndn-cache-performance-1.3.6.patch +Patch63: 0063-Ticket-49330-Add-endian-header-file-check-to-configu.patch +Patch64: 0064-Ticket-49257-only-register-modify-callbacks.patch +Patch65: 0065-Ticket-49291-slapi_search_internal_callback_pb-may-S.patch +Patch66: 0066-Ticket-49370-local-password-policies-should-use-the-.patch +Patch67: 0067-Ticket-49380-Crash-when-adding-invalid-replication.patch +Patch68: 0068-Ticket-49380-Add-CI-test.patch +Patch69: 0069-Ticket-49327-password-expired-control-not-sent-durin.patch +Patch70: 0070-Ticket-49379-Allowed-sasl-mapping-requires-restart.patch +Patch71: 0071-Fix-cherry-pick-error-from-sasl-mech-commit.patch +Patch72: 0072-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch +Patch73: 0073-Ticket-49180-backport-1.3.6-errors-log-filled-with-a.patch +Patch74: 0074-Ticket-48894-harden-valueset_array_to_sorted_quick-v.patch +Patch75: 0075-Ticket-49401-improve-valueset-sorted-performance-on-.patch +Patch76: 0076-Ticket-49401-Fix-compiler-incompatible-pointer-types.patch +Patch77: 0077-Ticket-48235-Remove-memberOf-global-lock.patch +Patch78: 0078-Ticket-49402-Adding-a-database-entry-with-the-same-d.patch +Patch79: 0079-Ticket-49439-cleanallruv-is-not-logging-information.patch +Patch80: 0080-Ticket-49436-double-free-in-COS-in-some-conditions.patch +Patch81: 0081-Ticket-49441-Import-crashes-with-large-indexed-binar.patch +Patch82: 0082-Ticket-49431-replicated-MODRDN-fails-breaking-replic.patch +Patch83: 0083-Ticket-49410-opened-connection-can-remain-no-longer-.patch +Patch84: 0084-Ticket-48118-backport-changelog-can-be-erronously-re.patch +Patch85: 0085-Ticket-49495-Fix-memory-management-is-vattr.patch +Patch86: 0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch +Patch87: 0087-Ticket-49509-Indexing-of-internationalized-matching-.patch +Patch88: 0088-Ticket-bz1525628-1.3.6-backport-invalid-password-mig.patch +Patch89: 0089-Ticket-49545-final-substring-extended-filter-search-.patch +Patch90: 0090-Ticket-49471-heap-buffer-overflow-in-ss_unescape.patch +Patch91: 0091-Ticket-49540-Indexing-task-is-reported-finished-too-.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -224,22 +234,19 @@ the LDAP server and command line utilities for server administration. Summary: Core libraries for 389 Directory Server Group: System Environment/Daemons BuildRequires: nspr-devel -BuildRequires: nss-devel >= 3.34 +BuildRequires: nss-devel BuildRequires: svrcore-devel >= 4.1.3 BuildRequires: openldap-devel BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: libicu-devel BuildRequires: pcre-devel +%if %{use_nunc_stans} BuildRequires: libtalloc-devel BuildRequires: libevent-devel BuildRequires: libtevent-devel -BuildRequires: systemd-devel -%if %{use_asan} -Requires: libasan -Requires: llvm %endif - +BuildRequires: systemd-devel %description libs Core libraries for the 389 Directory Server base package. These libraries @@ -252,12 +259,14 @@ Group: Development/Libraries Requires: %{name}-libs = %{version}-%{release} Requires: pkgconfig Requires: nspr-devel -Requires: nss-devel >= 3.34 +Requires: nss-devel Requires: svrcore-devel >= 4.1.3 Requires: openldap-devel +%if %{use_nunc_stans} Requires: libtalloc Requires: libevent Requires: libtevent +%endif Requires: systemd-libs %description devel @@ -283,8 +292,100 @@ BuildArch: noarch The lib389 CI tests that can be run against the Directory Server. %prep -%autosetup -p1 -n %{name}-%{version}%{?prerel} +%setup -q -n %{name}-%{version}%{?prerel} cp %{SOURCE2} README.devel +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 +%patch83 -p1 +%patch84 -p1 +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 +%patch90 -p1 +%patch91 -p1 %build @@ -292,14 +393,13 @@ OPENLDAP_FLAG="--with-openldap" %{?with_tmpfiles_d: TMPFILES_FLAG="--with-tmpfiles-d=%{with_tmpfiles_d}"} # hack hack hack https://bugzilla.redhat.com/show_bug.cgi?id=833529 NSSARGS="--with-svrcore-inc=%{_includedir} --with-svrcore-lib=%{_libdir} --with-nss-lib=%{_libdir} --with-nss-inc=%{_includedir}/nss3" +%if %{use_nunc_stans} +NUNC_STANS_FLAGS="--enable-nunc-stans" +%endif %if %{use_tcmalloc} TCMALLOC_FLAGS="--enable-tcmalloc" %endif -%if %{use_asan} -ASAN_FLAGS="--enable-asan --enable-debug" -%endif - # Rebuild the autotool artifacts now. autoreconf -fiv @@ -307,8 +407,8 @@ autoreconf -fiv --with-systemdsystemunitdir=%{_unitdir} \ --with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \ --with-perldir=/usr/bin \ - --with-systemdgroupname=%{groupname} $NSSARGS \ - --with-systemd $TCMALLOC_FLAGS $ASAN_FLAGS + --with-systemdgroupname=%{groupname} $NSSARGS $NUNC_STANS_FLAGS \ + --with-systemd $TCMALLOC_FLAGS # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS @@ -354,13 +454,6 @@ popd # make sure perl scripts have a proper shebang sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/script-templates/template-*.pl -## exclude 32-bit platforms from running tests -#%if %{_arch} != "s390x" && %{_arch} != "s390" && %{_arch} != "i386" && %{_arch} != "ppc" -#%check -## This checks the code, if it fails it prints why, then re-raises the fail to shortcircuit the rpm build#. -#if ! make DESTDIR="$RPM_BUILD_ROOT" check; then cat ./test-suite.log && false; fi -#%endif - %clean rm -rf $RPM_BUILD_ROOT @@ -391,9 +484,6 @@ if ! getent passwd $USERNAME >/dev/null ; then /usr/sbin/useradd -r -u $ALLOCATED_UID -g $GROUPNAME -d $HOMEDIR -s /sbin/nologin -c "user for 389-ds-base" $USERNAME fi -# Reload our sysctl before we restart (if we can) -sysctl --system &> $output; true - echo looking for instances in %{_sysconfdir}/%{pkgname} > $output 2>&1 || : instbase="%{_sysconfdir}/%{pkgname}" for dir in $instbase/slapd-* ; do @@ -427,9 +517,9 @@ echo remove pid files . . . >> $output 2>&1 || : echo upgrading instances . . . >> $output 2>&1 || : DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"` if [ -n "$DEBUGPOSTSETUPOPT" ] ; then - %{_sbindir}/setup-ds.pl -l $output2 -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : + %{_sbindir}/setup-ds.pl -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : else - %{_sbindir}/setup-ds.pl -l $output2 -u -s General.UpdateMode=offline >> $output 2>&1 || : + %{_sbindir}/setup-ds.pl -u -s General.UpdateMode=offline >> $output 2>&1 || : fi # restart instances that require it @@ -474,58 +564,13 @@ fi %config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname} %config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname}.systemd %{_datadir}/%{pkgname} -%{_datadir}/gdb/auto-load/* %{_unitdir} %{_bindir}/* -# We have to seperate this from being a glob to ensure the caps are applied. -%{_sbindir}/ns-slapd -%{_sbindir}/bak2db -%{_sbindir}/bak2db.pl -%{_sbindir}/cleanallruv.pl -%{_sbindir}/db2bak -%{_sbindir}/db2bak.pl -%{_sbindir}/db2index -%{_sbindir}/db2index.pl -%{_sbindir}/db2ldif -%{_sbindir}/db2ldif.pl -%{_sbindir}/dbmon.sh -%{_sbindir}/dbverify -%{_sbindir}/dn2rdn -%{_sbindir}/ds_selinux_enabled -%{_sbindir}/ds_selinux_port_query -%{_sbindir}/ds_systemd_ask_password_acl -%{_sbindir}/fixup-linkedattrs.pl -%{_sbindir}/fixup-memberof.pl -%{_sbindir}/ldif2db -%{_sbindir}/ldif2db.pl -%{_sbindir}/ldif2ldap -%{_sbindir}/migrate-ds.pl -%{_sbindir}/monitor -%{_sbindir}/ns-accountstatus.pl -%{_sbindir}/ns-activate.pl -%{_sbindir}/ns-inactivate.pl -%{_sbindir}/ns-newpwpolicy.pl -%{_sbindir}/remove-ds.pl -%{_sbindir}/restart-dirsrv -%{_sbindir}/restoreconfig -%{_sbindir}/saveconfig -%{_sbindir}/schema-reload.pl -%{_sbindir}/setup-ds.pl -%{_sbindir}/start-dirsrv -%{_sbindir}/status-dirsrv -%{_sbindir}/stop-dirsrv -%{_sbindir}/suffix2instance -%{_sbindir}/syntax-validate.pl -%{_sbindir}/upgradedb -%{_sbindir}/upgradednformat -%{_sbindir}/usn-tombstone-cleanup.pl -%{_sbindir}/verify-db.pl -%{_sbindir}/vlvindex +%{_sbindir}/* %{_libdir}/%{pkgname}/perl %{_libdir}/%{pkgname}/python %dir %{_libdir}/%{pkgname}/plugins %{_libdir}/%{pkgname}/plugins/*.so -%{_prefix}/lib/sysctl.d/* %dir %{_localstatedir}/lib/%{pkgname} %dir %{_localstatedir}/log/%{pkgname} %ghost %dir %{_localstatedir}/lock/%{pkgname} @@ -542,9 +587,10 @@ fi %{_libdir}/%{pkgname}/libslapd.so %{_libdir}/%{pkgname}/libns-dshttpd.so %{_mandir}/man3/* +%if %{use_nunc_stans} %{_libdir}/%{pkgname}/libnunc-stans.so %{_libdir}/%{pkgname}/libsds.so -%{_libdir}/%{pkgname}/libldaputil.so +%endif %{_libdir}/pkgconfig/* %files libs @@ -553,9 +599,10 @@ fi %dir %{_libdir}/%{pkgname} %{_libdir}/%{pkgname}/libslapd.so.* %{_libdir}/%{pkgname}/libns-dshttpd-*.so +%if %{use_nunc_stans} %{_libdir}/%{pkgname}/libnunc-stans.so.* %{_libdir}/%{pkgname}/libsds.so.* -%{_libdir}/%{pkgname}/libldaputil.so.* +%endif %files snmp %defattr(-,root,root,-) @@ -571,124 +618,77 @@ fi %{_sysconfdir}/%{pkgname}/dirsrvtests %changelog -* Tue Apr 3 2018 Matus Honek - 1.3.7.5-19 -- Bump version to 1.3.7.5-19 -- Resolves: Bug 1563107 - IPA server is not responding, all authentication and admin tests failed [rhel-7.5.z] - -* Mon Feb 12 2018 Mark Reynolds - 1.3.7.5-18 -- Bump version to 1.3.7.5-18 -- Resolves: Bug 1539082 - Fix memory leak - -* Mon Feb 12 2018 Mark Reynolds - 1.3.7.5.17 -- Bump version to 1.3.7.5.17 -- Resolves: Bug 1539082 - Child entry cenotaphs should not prevent the deletion of the parent -- Resolves: Bug 1540106 - CVE-2018-1054 - remote Denial of Service (DoS) via search filters in SetUnicodeStringFromUTF_8 -- Resolves: Bug 1535538 - CVE-2017-15135 - Authentication bypass due to lack of size check in slapi_ct_memcmp - -* Tue Feb 6 2018 Mark Reynolds - 1.3.7.5-16 -- Bump version to 1.3.7.5-16 -- Resolves: Bug 1542645 - Outgoing secure connection is failing with recent OpenLDAP - -* Tue Feb 6 2018 Mark Reynolds - 1.3.7.5-15 -- Bump version to 1.3.7.5-15 -- Resolves: Bug 1533828 - Server allows to set nsds5replicaid=65535 in the existing replica entry -- Resolves: Bug 1535515 - local password policies should use the same defaults as the global policy -- Resolves: Bug 1541108 - Allow CRL handling to be configurable for outgoing connections - -* Fri Jan 26 2018 Mark Reynolds - 1.3.7.5-14 -- Bump version to 1.3.7.5-14 -- Resolves: Bug 1519406 - New defects found in 389-ds-base-1.3.7.5-3.el7 (fix regression in -13) - -* Thu Jan 18 2018 Mark Reynolds - 1.3.7.5-13 -- Bump version to 1.3.7.5-13 -- Resolves: Bug 1533828 - Server allows to set nsds5replicaid=65535 in the existing replica entry -- Resolves: Bug 1519406 - New defects found in 389-ds-base-1.3.7.5-3.el7 -- Resolves: Bug 1534379 - CVE-2017-15134: Remote DoS via search filters in slapi_filter_sprintf in slapd/util.c -- Resolves: Bug 1533571 - memberof: schema violation error message is confusing as memberof will likely repair target entry -- Resolves: Bug 1535515 - local password policies should use the same defaults as the global policy - -* Fri Jan 12 2018 Mark Reynolds - 1.3.7.5-12 -- Bump version to 1.3.7.5-12 -- Resolves: Bug 1459946 - GetEffectiveRights gives false-negative with ACIs containing targetfilter -- Resolves: Bug 1507194 - cleanallruv could break replication if anchor csn in ruv originated in deleted replica -- Resolves: Bug 1517788 - password policy: minimum token length fails when the token length is equal to attribute length -- Resolves: Bug 1518287 - heap-use-after-free in csn_as -- Resolves: Bug 1531153 - Indexing of internationalized matching rules is failing -- Resolves: Bug 1517383 - ns-slapd segfaults with ERR - connection_release_nolock_ext - conn=0 fd=0 Attempt to release connection that is not acquired -- Resolves: Bug 1523183 - search with CoS attribute is getting slower after modifying/adding CosTemplate -- Resolves: Bug 1457315 - cmocka tests are not executed during rpm build -- Resolves: Bug 1516309 - After cleanALLruv, replication is looping on keep alive DEL - -* Fri Dec 8 2017 Mark Reynolds - 1.3.7.5-11 -- Bump version to 1.3.7.5-11 -- Resolves: Bug 1518069 - heap-buffer-overflow in ss_unescape -- Resolves: Bug 1516676 - gssapi authentication fails after upgrading 389-ds-base -- Resolves: Bug 1511885 - Automatically load /usr/lib/sysctl.d/70-dirsrv.conf after installing 389-ds-base -- Resolves: Bug 1517980 - stack-buffer-overflow in slapi_pblock_get - -* Thu Nov 16 2017 Mark Reynolds - 1.3.7.5-10 -- Bump version to 1.3.7.5-10 -- Resolves: Bug 1464463 - Replication fails to start with CBCA (Certificate-Based Client Authentication) while FIPS mode is enabled. -- Resolves: Bug 1465383 - Segmentation fault in valueset_array_to_sorted_quick -- Resolves: Bug 1510865 - python-ldap is not a dependency of 389-ds-base -- Resolves: Bug 1513467 - IPA upgrade fails for latest ipa package -- Resolves: Bug 1192099 - IPA server replication broken, after DS stop-start, due to changelog reset -- Resolves: Bug 1445188 - Misleading error message - Incoming BER Element was 3 bytes -- Resolves: Bug 1498980 - heap corruption during import -- Resolves: Bug 1511462 - scope one searches give incorrect results -- Resolves: Bug 1514033 - opened connection are hanging, no longer poll - -* Fri Nov 3 2017 Mark Reynolds - 1.3.7.5-9 -- Bump version to 1.3.7.5-9 -- Resolves: Bug 1271208 - Fix copy and paste error - -* Fri Nov 3 2017 Mark Reynolds - 1.3.7.5-8 -- Bump version to 1.3.7.5-8 -- Resolves: Bug 1509016 - cleanallruv task is not logging any information - -* Fri Nov 3 2017 Mark Reynolds - 1.3.7.5-7 -- Bump version to 1.3.7.5-7 -- Resolves: Bug 1474100 - Use of uninitialized value in string ne at /usr/bin/logconv.pl -- Resolves: Bug 1506425 - Improve valueset sort performance during valueset purging -- Resolves: Bug 1505046 - [abrt] 389-ds-base: SLL_Next(): ns-slapd killed by SIGSEGV -- Resolves: Bug 1271208 - nsds5ReplicaProtocolTimeout attribute accepts negative values - -* Fri Oct 20 2017 Mark Reynolds - 1.3.7.5-6 -- Bump version to 1.3.7.5-6 -- Resolves: Bug 1488836 - directory server fails to start because maxdisksize -- Resolves: Bug 1474100 - Use of uninitialized value in string ne at /usr/bin/logconv.pl -- Resolves: Bug 1447308 - Add option to show full un-ellipsized output in status-dirsrv -- Resolves: Bug 1438526 - Server allows to set any nsds5replicaid in the existing replica entry -- Resolves: Bug 1185774 - Missing warning for invalid replica backoff configuration - -* Wed Oct 18 2017 Mark Reynolds - 1.3.7.5-5 -- Bump version to 1.3.7.5-5 -- Resolves: Bug 1476207 - Enabling instance service doesn't work -- Resolves: Bug 1434335 - Errors log filled with attrlist_replace - attr_replace -- Resolves: Bug 1453155 - unable to retrieve specific cosAttribute when subtree password policy is configured -- Resolves: Bug 1459965 - repl-monitor - matches null string many times in regex -- Resolves: Bug 1463204 - Adding a database entry fails if the same database was deleted after an import -- Resolves: Bug 1469567 - Activating roles returns error 16 -- Resolves: Bug 1498773 - Installation of ipa fails with crash in topology plugin -- Resolves: Bug 1501058 - [memberOf Plugin] bulk deleting users causes deadlock when there are multiple backends -- Resolves: Bug 1352121 - [RFE] allow to enable MemberOf plugin in dedicated consumer - -* Mon Oct 2 2017 Mark Reynolds - 1.3.7.5-4 -- Bump version to 1.3.7.5-4 -- Fix coverity warnings from convscan -- Improve atomics - -* Wed Sep 27 2017 Mark Reynolds - 1.3.7.5-3 -- Bump version to 1.3.7.5-3 -- specfile remove cap_net_bind_service+ep from ns-slapd - -* Wed Sep 27 2017 Mark Reynolds - 1.3.7.5-2 -- Bump version to 1.3.7.5-2 -- specfile updates: add asan support, make nunc-stans default, and general cleanup - -* Fri Sep 22 2017 Mark Reynolds - 1.3.7.5-1 -- Bump version to 1.3.7.5-1 -- Resolves: Bug 1470169 - Rebase 389-ds-base in RHEL 7.5 to 1.3.7 +* Mon Mar 12 2018 Mark Reynolds - 1.3.6.1-29 +- Bump version to 1.3.6.1-29 +- Resolves: Bug 1553602 - ipa-server-install fails with Error: Upgrade failed with no such entry [rhel-7.4.z] + +* Mon Feb 26 2018 Mark Reynolds - 1.3.6.1-28 +- Bump version to 1.3.6.1-28 +- Resolves: Bug 1540105 - CVE-2018-1054 - remote Denial of Service (DoS) via search filters in SetUnicodeStringFromUTF_8 + +* Tue Feb 13 2018 Mark Reynolds - 1.3.6.1-27 +- Bump version to 1.3.6.1-27 +- Resolves: Bug 1536343 - Indexing of internationalized matching rules is failing +- Resolves: Bug 1535539 - CVE-2017-15135 - Authentication bypass due to lack of size check in slapi_ct_memcmp function +- Resolves: Bug 1540105 - CVE-2018-1054 - remote Denial of Service (DoS) via search filters in SetUnicodeStringFromUTF_8 + +* Tue Jan 16 2018 Mark Reynolds - 1.3.6.1-26 +- Bump version to 1.3.6.1-26 +- Resolves: Bug 1534430 - crash in slapi_filter_sprintf + +* Mon Dec 18 2017 Mark Reynolds - 1.3.6.1-25 +- Bump version to 1.3.6.1-25 +- Resolves: Bug 1526928 - search with CoS attribute is getting slower after modifying/adding CosTemplate +- Resolves: Bug 1523505 - opened connection are hanging, no longer poll +- Resolves: Bug 1523507 - IPA server replication broken, after DS stop-start, due to changelog reset + +* Fri Nov 10 2017 Mark Reynolds - 1.3.6.1-24 +- Bump version to 1.3.6.1-24 +- Resolves: Bug 1508978 - replicated MODRDN fails breaking replication +- Resolves: Bug 1511940 - heap corruption during import +- Resolves: Bug 1510319 - [abrt] 389-ds-base: SLL_Next(): ns-slapd killed by SIGSEGV +- Resolves: Bug 1509347 - cleanallruv task is not logging any information + +* Fri Oct 27 2017 Mark Reynolds - 1.3.6.1-23 +- Bump version to 1.3.6.1-23 +- Resolves: Bug 1504536 - [memberOf Plugin] bulk deleting users causes deadlock when there are multiple backends +- Resolves: Bug 1503001 - Adding a database entry fails if the same database was deleted after an import +- Resolves: Bug 1506912 - Improve valueset sort performance during valueset purging + +* Mon Oct 9 2017 Mark Reynolds - 1.3.6.1-22 +- Bump version to 1.3.6.1-22 +- Resolves: Bug 1499668 - Errors log filled with attrlist_replace + +* Thu Oct 5 2017 Mark Reynolds - 1.3.6.1-21 +- Bump verions to 1.3.6.1-21 +- Resolves: Bug 1498958 - unable to retrieve specific cosAttribute when subtree password policy is configured + +* Mon Sep 18 2017 Mark Reynolds - 1.3.6.1-20 +- Bump verions to 1.3.6.1-20 +- Resolves: Bug 1489693 - PasswordCheckSyntax attribute fails to validate cn, sn, uid +- Resovles: Bug 1492829 - patch should of been applied to 7.4 but got missed +- Resolves: Bug 1486128 - Performance issues with RHDS 10 - NDN cache investigation +- Resolves: Bug 1489694 - crash in send_ldap_result +- Resolves: Bug 1491778 - crash when adding invalid repl agmt +- Resolves: Bug 1492830 - password expired control not sent +- Resolves: Bug 1492833 - sasl-mechanisms removed during upgrade + +* Mon Aug 21 2017 Mark Reynolds - 1.3.6.1-19 +- Bump version to 1.3.6.1-19 +- Remove old mozldap and db4 requirements +- Resolves: Bug 1483865 - Crash while binding to a server during replication online init + +* Tue Aug 8 2017 Mark Reynolds - 1.3.6.1-18 +- Bump version to 1.3.6.1-18 +- Require srvcore 4.1.3 +- Resolves: Bug 1479757 - dse.ldif and fsync +- Resolves: Bug 1479755 - backup fails if changelog is enabled +- Resolves: Bug 1479756 - Locked account provides different return code if password is correct + +* Mon Jul 31 2017 Mark Reynolds - 1.3.6.1-17 +- Bump version to 1.3.6.1-17 +- Resolves: Bug 1476161 - replication halt - pending list first CSN not committed, pending list increasing +- Resolves: Bug 1476162 - Change the retrochangelog default cache size * Tue Jun 6 2017 Mark Reynolds - 1.3.6.1-16 - Bump version to 1.3.6.1-16