diff --git a/SOURCES/0013-Ticket-49915-Master-ns-slapd-had-100-CPU-usage-after.patch b/SOURCES/0013-Ticket-49915-Master-ns-slapd-had-100-CPU-usage-after.patch
new file mode 100644
index 0000000..34d9d01
--- /dev/null
+++ b/SOURCES/0013-Ticket-49915-Master-ns-slapd-had-100-CPU-usage-after.patch
@@ -0,0 +1,354 @@
+From 6d67faa0de58cb0b66fc72d43f24b1c9669f88f8 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Mon, 3 Sep 2018 15:36:52 +0200
+Subject: [PATCH] Ticket 49915 - Master ns-slapd had 100% CPU usage after
+ starting replication and replication cannot finish
+
+Bug Description:
+	During a total initialization the supplier builds a candidate list of the entries to send.
+	Because of https://fedorahosted.org/389/ticket/48755, the candidate list relies on parentid attribute.
+	All entries, except tombstones and suffix itself, have parentid.
+	There is an assumption that the first found key (i.e. '=1') contains the suffix children.
+	So when it finally finds the suffix key it adds its children to a leftover list rather to the candidate list.
+	Later idl_new_range_fetch loops for ever trying to add suffix children from leftover to candidate list.
+
+Fix Description:
+	The fix consist to store the suffix_id (if it does not exist already) in the parentid index (with the key '=0').
+	Then get it to detect the suffix key from the index in idl_new_range_fetch.
+
+https://pagure.io/389-ds-base/issue/49915
+
+Reviewed by: Ludwig Krispenz, William Brown (thanks !)
+
+Platforms tested: F27
+
+Flag Day: no
+
+Doc impact: no
+---
+ .../plugins/replication/repl5_tot_protocol.c  |  48 ++++++++
+ ldap/servers/slapd/back-ldbm/dblayer.c        |   8 ++
+ ldap/servers/slapd/back-ldbm/idl_new.c        |  34 +++++-
+ ldap/servers/slapd/back-ldbm/index.c          | 114 ++++++++++++++++++
+ ldap/servers/slapd/slapi-plugin.h             |  10 +-
+ 5 files changed, 209 insertions(+), 5 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
+index ee3c9dcb0..1dbbe694f 100644
+--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
++++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
+@@ -283,6 +283,53 @@ repl5_tot_waitfor_async_results(callback_data *cb_data)
+     }
+ }
+ 
++/* This routine checks that the entry id of the suffix is
++ * stored in the parentid index
++ * The entry id of the suffix is stored with the equality key 0 (i.e. '=0')
++ * It first checks if the key '=0' exists. If it does not exists or if the first value
++ * stored with that key, does not match the suffix entryid (stored in the suffix entry
++ * from id2entry.db then it updates the value
++ */
++static void
++check_suffix_entryID(Slapi_Backend *be, Slapi_Entry *suffix)
++{
++    u_int32_t entryid;
++    char *entryid_str;
++    struct _back_info_index_key bck_info;
++
++    /* we are using a specific key in parentid to store the suffix entry id: '=0' */
++    bck_info.index = SLAPI_ATTR_PARENTID;
++    bck_info.key = "0";
++
++    /* First try to retrieve from parentid index the suffix entryID */
++    if (slapi_back_get_info(be, BACK_INFO_INDEX_KEY, (void **) &bck_info)) {
++        slapi_log_err(SLAPI_LOG_REPL, "check_suffix_entryID", "Total update: fail to retrieve suffix entryID. Let's try to write it\n");
++    }
++
++    /* Second retrieve the suffix entryid from the suffix entry itself */
++    entryid_str = slapi_entry_attr_get_charptr(suffix, "entryid");
++    if (entryid_str == NULL) {
++        char *dn;
++        dn = slapi_entry_get_ndn(suffix);
++        slapi_log_err(SLAPI_LOG_ERR, "check_suffix_entryID", "Unable to retrieve entryid of the suffix entry %s\n", dn ? dn : "<unknown>");
++        slapi_ch_free_string(&entryid_str);
++        return;
++    }
++    entryid = (u_int32_t) atoi(entryid_str);
++    slapi_ch_free_string(&entryid_str);
++
++    if (!bck_info.key_found || bck_info.id != entryid) {
++        /* The suffix entryid is not present in parentid index
++         *  or differs from what is in id2entry (entry 'suffix')
++         * So write it to the parentid so that the range index used
++         * during total init will know the entryid of the suffix
++         */
++        bck_info.id = entryid;
++        if (slapi_back_set_info(be, BACK_INFO_INDEX_KEY, (void **) &bck_info)) {
++            slapi_log_err(SLAPI_LOG_ERR, "check_suffix_entryID", "Total update: fail to register suffix entryid, continue assuming suffix is the first entry\n");
++        }
++    }
++}
+ 
+ /*
+  * Completely refresh a replica. The basic protocol interaction goes
+@@ -467,6 +514,7 @@ retry:
+         replica_subentry_check(area_sdn, rid);
+ 
+         /* Send the subtree of the suffix in the order of parentid index plus ldapsubentry and nstombstone. */
++        check_suffix_entryID(be, suffix);
+         slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(area_sdn),
+                                      LDAP_SCOPE_SUBTREE, "(parentid>=1)", NULL, 0, ctrls, NULL,
+                                      repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), OP_FLAG_BULK_IMPORT);
+diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
+index e84cb7695..fa931ccbf 100644
+--- a/ldap/servers/slapd/back-ldbm/dblayer.c
++++ b/ldap/servers/slapd/back-ldbm/dblayer.c
+@@ -7295,6 +7295,10 @@ ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info)
+         *(int *)info = entryrdn_get_switch();
+         break;
+     }
++    case BACK_INFO_INDEX_KEY : {
++        rc = get_suffix_key(be, (struct _back_info_index_key *)info);
++        break;
++    }
+     default:
+         break;
+     }
+@@ -7311,6 +7315,10 @@ ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info)
+     }
+ 
+     switch (cmd) {
++    case BACK_INFO_INDEX_KEY : {
++        rc = set_suffix_key(be, (struct _back_info_index_key *)info);
++        break;
++    }
+     default:
+         break;
+     }
+diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
+index 4e28e3fc2..102265c47 100644
+--- a/ldap/servers/slapd/back-ldbm/idl_new.c
++++ b/ldap/servers/slapd/back-ldbm/idl_new.c
+@@ -320,6 +320,9 @@ typedef struct _range_id_pair
+  * In the total update (bulk import), an entry requires its ancestors already added.
+  * To guarantee it, the range search with parentid is used with setting the flag
+  * SLAPI_OP_RANGE_NO_IDL_SORT in operator.
++ * In bulk import the range search is parentid>=1 to retrieve all the entries
++ * But we need to order the IDL with the parents first => retrieve the suffix entry ID
++ * to store the children
+  *
+  * If the flag is set,
+  * 1. the IDList is not sorted by the ID.
+@@ -366,6 +369,23 @@ idl_new_range_fetch(
+     if (NULL == flag_err) {
+         return NULL;
+     }
++    if (operator & SLAPI_OP_RANGE_NO_IDL_SORT) {
++            struct _back_info_index_key bck_info;
++            int rc;
++            /* We are doing a bulk import
++             * try to retrieve the suffix entry id from the index
++             */
++
++            bck_info.index = SLAPI_ATTR_PARENTID;
++            bck_info.key = "0";
++
++            if (rc = slapi_back_get_info(be, BACK_INFO_INDEX_KEY, (void **)&bck_info)) {
++                slapi_log_err(SLAPI_LOG_WARNING, "idl_new_range_fetch", "Total update: fail to retrieve suffix entryID, continue assuming it is the first entry\n");
++            }
++            if (bck_info.key_found) {
++                suffix = bck_info.id;
++            }
++    }
+ 
+     if (NEW_IDL_NOOP == *flag_err) {
+         return NULL;
+@@ -455,7 +475,7 @@ idl_new_range_fetch(
+             *flag_err = LDAP_TIMELIMIT_EXCEEDED;
+             goto error;
+         }
+-        if (operator&SLAPI_OP_RANGE_NO_IDL_SORT) {
++        if (operator & SLAPI_OP_RANGE_NO_IDL_SORT) {
+             key = (ID)strtol((char *)cur_key.data + 1, (char **)NULL, 10);
+         }
+         while (PR_TRUE) {
+@@ -487,9 +507,13 @@ idl_new_range_fetch(
+             /* note the last id read to check for dups */
+             lastid = id;
+             /* we got another ID, add it to our IDL */
+-            if (operator&SLAPI_OP_RANGE_NO_IDL_SORT) {
+-                if (count == 0) {
+-                    /* First time.  Keep the suffix ID. */
++            if (operator & SLAPI_OP_RANGE_NO_IDL_SORT) {
++                if ((count == 0) && (suffix == 0)) {
++                    /* First time.  Keep the suffix ID. 
++                     * note that 'suffix==0' mean we did not retrieve the suffix entry id
++                     * from the parentid index (key '=0'), so let assume the first
++                     * found entry is the one from the suffix
++                     */
+                     suffix = key;
+                     idl_rc = idl_append_extend(&idl, id);
+                 } else if ((key == suffix) || idl_id_is_in_idlist(idl, key)) {
+@@ -615,9 +639,11 @@ error:
+     }
+     if (operator&SLAPI_OP_RANGE_NO_IDL_SORT) {
+         size_t remaining = leftovercnt;
++
+         while(remaining > 0) {
+             for (size_t i = 0; i < leftovercnt; i++) {
+                 if (leftover[i].key > 0 && idl_id_is_in_idlist(idl, leftover[i].key) != 0) {
++                    /* if the leftover key has its parent in the idl */
+                     idl_rc = idl_append_extend(&idl, leftover[i].id);
+                     if (idl_rc) {
+                         slapi_log_err(SLAPI_LOG_ERR, "idl_new_range_fetch",
+diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
+index 222f64dff..dea6e9a3e 100644
+--- a/ldap/servers/slapd/back-ldbm/index.c
++++ b/ldap/servers/slapd/back-ldbm/index.c
+@@ -1236,6 +1236,120 @@ error:
+     return ret;
+ }
+ 
++/* This routine add in a given index (parentid)
++ * the key/value = '=0'/<suffix entryID>
++ * Input: 
++ *      info->key contains the key to lookup (i.e. '0')
++ *      info->index index name used to retrieve syntax and db file
++ *      info->id  the entryID of the suffix
++ */
++int
++set_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info)
++{
++    struct ldbminfo *li;
++    int rc;
++    back_txn txn;
++    Slapi_Value *sv_key[2];
++    Slapi_Value tmpval;
++
++    if (info->index== NULL || info->key == NULL) {
++        slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Invalid index %s or key %s\n",
++                info->index ? info->index : "NULL",
++                info->key ? info->key : "NULL");
++        return -1;
++    }
++    
++    /* Start a txn */
++    li = (struct ldbminfo *)be->be_database->plg_private;
++    dblayer_txn_init(li, &txn);
++    if (rc = dblayer_txn_begin(be, txn.back_txn_txn, &txn)) {
++        slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): txn begin fails\n",
++                  info->index, info->key, info->id);
++        return rc;
++    }
++
++    sv_key[0] = &tmpval;
++    sv_key[1] = NULL;
++    slapi_value_init_string(sv_key[0], info->key);
++
++    if (rc = index_addordel_values_sv(be, info->index, sv_key, NULL, info->id, BE_INDEX_ADD, &txn)) {
++        value_done(sv_key[0]);
++        dblayer_txn_abort(be, &txn);
++        slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): index_addordel_values_sv fails\n",
++                  info->index, info->key, info->id);
++        return rc;
++    }
++
++    value_done(sv_key[0]);
++    if (rc = dblayer_txn_commit(be, &txn)) {
++        slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): commit fails\n",
++                  info->index, info->key, info->id);
++        return rc;
++    }
++
++    return 0;
++}
++/* This routine retrieves from a given index (parentid)
++ * the key/value = '=0'/<suffix entryID>
++ * Input: 
++ *      info->key contains the key to lookup (i.e. '0')
++ *      info->index index name used to retrieve syntax and db file
++ * Output
++ *      info->id It returns the first id that is found for the key.
++ *               If the key is not found, or there is no value for the key
++ *               it contains '0'
++ *      info->key_found  Boolean that says if the key leads to a valid ID in info->id
++ */
++int
++get_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info)
++{
++    struct berval bv;
++    int err;
++    IDList *idl = NULL;
++    ID id;
++    int rc = 0;
++
++    if (info->index== NULL || info->key == NULL) {
++        slapi_log_err(SLAPI_LOG_ERR, "get_suffix_key", "Invalid index %s or key %s\n",
++                info->index ? info->index : "NULL",
++                info->key ? info->key : "NULL");
++        return -1;
++    }
++
++    /* This is the key to retrieve */
++    bv.bv_val = info->key;
++    bv.bv_len = strlen(bv.bv_val);
++
++    /* Assuming we are not going to find the key*/
++    info->key_found = PR_FALSE;
++    id = 0;
++    idl = index_read(be, info->index, indextype_EQUALITY, &bv, NULL, &err);
++
++    if (idl == NULL) {
++        if (err != 0 && err != DB_NOTFOUND) {
++            slapi_log_err(SLAPI_LOG_ERR, "get_suffix_key", "Fail to read key %s (err=%d)\n",
++                    info->key ? info->key : "NULL",
++                    err);
++            rc = err;
++        }
++    } else {
++        /* info->key was found */
++        id = idl_firstid(idl);
++        if (id != NOID) {
++            info->key_found = PR_TRUE;
++        } else {
++            /* there is no ID in that key, make it as it was not found */
++            id = 0;
++        }
++        idl_free(&idl);
++    }
++
++    /* now set the returned id */
++    info->id = id;
++
++    return rc;
++}
++
+ IDList *
+ index_range_read_ext(
+     Slapi_PBlock *pb,
+diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
+index 0646cdfdd..4b75654e7 100644
+--- a/ldap/servers/slapd/slapi-plugin.h
++++ b/ldap/servers/slapd/slapi-plugin.h
+@@ -7763,9 +7763,17 @@ enum
+     BACK_INFO_CRYPT_DECRYPT_VALUE, /* Ctrl: clcrypt_decrypt_value */
+     BACK_INFO_DIRECTORY,           /* Get the directory path */
+     BACK_INFO_LOG_DIRECTORY,       /* Get the txn log directory */
+-    BACK_INFO_IS_ENTRYRDN          /* Get the flag for entryrdn */
++    BACK_INFO_IS_ENTRYRDN,         /* Get the flag for entryrdn */
++    BACK_INFO_INDEX_KEY            /* Get the status of a key in an index */
+ };
+ 
++struct _back_info_index_key
++{
++    char *index;              /* input: name of the index (parentid) */
++    char *key;                /* input: searched key (0) with equality -> '=0' */
++    PRBool key_found;         /* output: TRUE if '=0' is found in the index */
++    u_int32_t id;             /* output: if key_found it is the first value (suffix entryID) */
++};
+ struct _back_info_crypt_init
+ {
+     char *dn;                  /* input -- entry to store nsSymmetricKey */
+-- 
+2.17.2
+
diff --git a/SOURCES/0014-Ticket-49950-PassSync-not-setting-pwdLastSet-attribu.patch b/SOURCES/0014-Ticket-49950-PassSync-not-setting-pwdLastSet-attribu.patch
new file mode 100644
index 0000000..0395971
--- /dev/null
+++ b/SOURCES/0014-Ticket-49950-PassSync-not-setting-pwdLastSet-attribu.patch
@@ -0,0 +1,521 @@
+From 0d2456fd9e2678f6db075b224528727b741ff205 Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Fri, 14 Sep 2018 11:24:35 -0400
+Subject: [PATCH] Ticket 49950 -  PassSync not setting pwdLastSet attribute in
+ Active Directory after Pw update from LDAP sync for normal user
+
+Bug Description:
+
+If a user's password was reset by an "Admin" or directory manager, the
+password policy requires a user must change their password after it's
+been "reset", and the user then resets their password in DS, this
+information was not sent to AD.  Then if the user logged in AD after
+resetting their password in DS they still get forced to change their
+password again in AD.
+
+Fix Description:
+
+When sending a password update to AD, and AD is enforcing password must
+be reset, check if the user's did reset thier password.  If so, set the
+correct "pwdLastSet" value to prevent AD from forcing that user to
+change their password again.
+
+But this only works going from DS to AD.  The information needed to make
+it work from AD -> DS is not available to passSync, and if it was available
+it could not be correctly sent to DS anyway (not without a major redesign).
+
+Side Note:
+
+Also moved iand consolidated the function "fetch_attr" to util.c.  It
+was reused and redefined in many plugins.  So I added the definition
+to slapi-plugin.h and removed the duplicate definitions.
+
+https://pagure.io/389-ds-base/issue/49950
+
+Reviewed by: tbordaz(Thanks!)
+
+(cherry picked from commit d9437be2e60fdbd6a5f1364f5887e1a3c89cda68)
+(cherry picked from commit ac500d378aa22d5e818b110074ac9cd3e421e38d)
+---
+ ldap/servers/plugins/automember/automember.c  | 20 -----
+ ldap/servers/plugins/linkedattrs/fixup_task.c | 20 -----
+ ldap/servers/plugins/memberof/memberof.c      | 17 ----
+ .../plugins/posix-winsync/posix-group-task.c  | 18 +---
+ .../replication/repl5_replica_config.c        | 13 ---
+ .../replication/windows_protocol_util.c       | 90 ++++++++++++++-----
+ .../plugins/schema_reload/schema_reload.c     | 17 ----
+ ldap/servers/plugins/syntaxes/validate_task.c | 20 -----
+ ldap/servers/slapd/slapi-plugin.h             |  2 +
+ ldap/servers/slapd/task.c                     | 17 ----
+ ldap/servers/slapd/test-plugins/sampletask.c  | 16 ----
+ ldap/servers/slapd/util.c                     | 17 ++++
+ 12 files changed, 89 insertions(+), 178 deletions(-)
+
+diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
+index c91aa4e8e..d982d49a3 100644
+--- a/ldap/servers/plugins/automember/automember.c
++++ b/ldap/servers/plugins/automember/automember.c
+@@ -74,7 +74,6 @@ static void automember_free_regex_rule(struct automemberRegexRule *rule);
+ static int automember_parse_grouping_attr(char *value, char **grouping_attr, char **grouping_value);
+ static int automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
+ static int automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *grouping_attr, char *grouping_value, PRFileDesc *ldif_fd);
+-const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
+ 
+ /*
+  * task functions
+@@ -1927,25 +1926,6 @@ typedef struct _task_data
+     int scope;
+ } task_data;
+ 
+-/*
+- * extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Value *val = NULL;
+-    Slapi_Attr *attr;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0) {
+-        return default_val;
+-    }
+-    slapi_attr_first_value(attr, &val);
+-
+-    return slapi_value_get_string(val);
+-}
+-
+ static void
+ automember_task_destructor(Slapi_Task *task)
+ {
+diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
+index 900ee1135..4929714b4 100644
+--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
++++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
+@@ -22,7 +22,6 @@ static void linked_attrs_fixup_task_thread(void *arg);
+ static void linked_attrs_fixup_links(struct configEntry *config);
+ static int linked_attrs_remove_backlinks_callback(Slapi_Entry *e, void *callback_data);
+ static int linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data);
+-static const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
+ 
+ /*
+  * Function Implementations
+@@ -459,22 +458,3 @@ done:
+ 
+     return rc;
+ }
+-
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0) {
+-        return default_val;
+-    }
+-
+-    slapi_attr_first_value(attr, &val);
+-
+-    return slapi_value_get_string(val);
+-}
+diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
+index 87313ff19..26236dc68 100644
+--- a/ldap/servers/plugins/memberof/memberof.c
++++ b/ldap/servers/plugins/memberof/memberof.c
+@@ -142,7 +142,6 @@ static int memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *con
+ static int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, Slapi_DN *group_sdn, Slapi_DN *op_this_sdn, Slapi_DN *replace_with_sdn, Slapi_DN *op_to_sdn, memberofstringll *stack);
+ static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
+ static void memberof_task_destructor(Slapi_Task *task);
+-static const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
+ static void memberof_fixup_task_thread(void *arg);
+ static int memberof_fix_memberof(MemberOfConfig *config, Slapi_Task *task, task_data *td);
+ static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
+@@ -2871,22 +2870,6 @@ done:
+                   "memberof_fixup_task_thread - refcount decremented.\n");
+ }
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-    slapi_attr_first_value(attr, &val);
+-    return slapi_value_get_string(val);
+-}
+-
+ int
+ memberof_task_add(Slapi_PBlock *pb,
+                   Slapi_Entry *e,
+diff --git a/ldap/servers/plugins/posix-winsync/posix-group-task.c b/ldap/servers/plugins/posix-winsync/posix-group-task.c
+index b4c507595..d8b6addd4 100644
+--- a/ldap/servers/plugins/posix-winsync/posix-group-task.c
++++ b/ldap/servers/plugins/posix-winsync/posix-group-task.c
+@@ -42,22 +42,6 @@ posix_group_fixup_task_thread(void *arg);
+ static int
+ posix_group_fix_memberuid_callback(Slapi_Entry *e, void *callback_data);
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-    slapi_attr_first_value(attr, &val);
+-    return slapi_value_get_string(val);
+-}
+-
+ /* e configEntry */
+ int
+ posix_group_task_add(Slapi_PBlock *pb __attribute__((unused)),
+@@ -82,7 +66,7 @@ posix_group_task_add(Slapi_PBlock *pb __attribute__((unused)),
+ 
+     /* get arg(s) */
+     /* default: set replication basedn */
+-    if ((dn = fetch_attr(e, "basedn", slapi_sdn_get_dn(posix_winsync_config_get_suffix()))) == NULL) {
++    if ((dn = fetch_attr(e, "basedn", (char *)slapi_sdn_get_dn(posix_winsync_config_get_suffix()))) == NULL) {
+         *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+         rv = SLAPI_DSE_CALLBACK_ERROR;
+         goto out;
+diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
+index ea430d9a4..84e02639b 100644
+--- a/ldap/servers/plugins/replication/repl5_replica_config.c
++++ b/ldap/servers/plugins/replication/repl5_replica_config.c
+@@ -1353,19 +1353,6 @@ replica_execute_cleanruv_task(Object *r, ReplicaId rid, char *returntext __attri
+     return LDAP_SUCCESS;
+ }
+ 
+-const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-
+-    slapi_attr_first_value(attr, &val);
+-    return slapi_value_get_string(val);
+-}
+-
+ static int
+ replica_cleanall_ruv_task(Slapi_PBlock *pb __attribute__((unused)),
+                           Slapi_Entry *e,
+diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
+index f350b6d34..f6898d018 100644
+--- a/ldap/servers/plugins/replication/windows_protocol_util.c
++++ b/ldap/servers/plugins/replication/windows_protocol_util.c
+@@ -720,39 +720,79 @@ send_password_modify(Slapi_DN *sdn,
+     } else {
+         Slapi_Attr *attr = NULL;
+         int force_reset_pw = 0;
++        int pwd_already_reset = 0;
++        int ds_must_change = config_get_pw_must_change();
++
+         /*
+-             * If AD entry has password must change flag is set,
+-             * we keep the flag (pwdLastSet == 0).
+-             * msdn.microsoft.com: Windows Dev Centor - Desktop
+-             * To force a user to change their password at next logon,
+-             * set the pwdLastSet attribute to zero (0).
+-             */
++         * If AD entry has password must change flag is set,
++         * we keep the flag (pwdLastSet == 0).
++         * msdn.microsoft.com: Windows Dev Centor - Desktop
++         * To force a user to change their password at next logon,
++         * set the pwdLastSet attribute to zero (0).
++         */
+         if (remote_entry &&
+             (0 == slapi_entry_attr_find(remote_entry, "pwdLastSet", &attr)) &&
+-            attr) {
++            attr)
++        {
+             Slapi_Value *v = NULL;
+             int i = 0;
++
+             for (i = slapi_attr_first_value(attr, &v);
+                  v && (i != -1);
+-                 i = slapi_attr_next_value(attr, i, &v)) {
++                 i = slapi_attr_next_value(attr, i, &v))
++            {
+                 const char *s = slapi_value_get_string(v);
+                 if (NULL == s) {
+                     continue;
+                 }
+                 if (0 == strcmp(s, "0")) {
+-                    slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
+-                                  "%s: AD entry %s set \"user must change password at next logon\". ",
+-                                  agmt_get_long_name(prp->agmt), slapi_entry_get_dn(remote_entry));
+                     force_reset_pw = 1;
++                    if (ds_must_change) {
++                        /*
++                         * DS already enforces "password must be changed after reset".
++                         * Do an internal search and check the passwordExpirationtime
++                         * to see if is it actually needs to be reset.  If it doesn't,
++                         * then set pwdLastSet to -1
++                         */
++                        char *expiration_val;
++                        int rc = 0;
++                        Slapi_DN *local_sdn = NULL;
++
++                        rc = map_entry_dn_inbound(remote_entry, &local_sdn, prp->agmt);
++                        if ((0 == rc) && local_sdn) {
++                            Slapi_Entry *local_entry = NULL;
++                            /* Get the local entry if it exists */
++                            rc = windows_get_local_entry(local_sdn, &local_entry);
++                            if ((0 == rc) && local_entry) {
++                                expiration_val = (char *)fetch_attr(local_entry, "passwordExpirationtime", NULL);
++                                if (expiration_val && parse_genTime(expiration_val) != NO_TIME){
++                                    /* The user did reset their password */
++                                    slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
++                                        "send_password_modify - entry (%s) password was reset by user send that info to AD\n",
++                                        slapi_sdn_get_dn(local_sdn));
++                                    pwd_already_reset = 1;
++                                    force_reset_pw = 0;
++                                }
++                                slapi_entry_free(local_entry);
++                            }
++                        }
++                        slapi_sdn_free(&local_sdn);
++                    } else {
++                        slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
++                                      "%s: AD entry %s set \"user must change password at next logon\n",
++                                      agmt_get_long_name(prp->agmt), slapi_entry_get_dn(remote_entry));;
++                    }
+                 }
+             }
+         }
+-        /* We will attempt to bind to AD with the new password first. We do
+-             * this to avoid playing a password change that originated from AD
+-             * back to AD.  If we just played the password change back, then
+-             * both sides would be in sync, but AD would contain the new password
+-             * twice in it's password history, which undermines the password
+-             * history policies in AD. */
++        /*
++         * We will attempt to bind to AD with the new password first. We do
++         * this to avoid playing a password change that originated from AD
++         * back to AD.  If we just played the password change back, then
++         * both sides would be in sync, but AD would contain the new password
++         * twice in it's password history, which undermines the password
++         * history policies in AD.
++         */
+         if (windows_check_user_password(prp->conn, sdn, password)) {
+             char *quoted_password = NULL;
+             /* AD wants the password in quotes ! */
+@@ -792,9 +832,18 @@ send_password_modify(Slapi_DN *sdn,
+                     pw_mod.mod_bvalues = bvals;
+ 
+                     pw_mods[0] = &pw_mod;
+-                    if (force_reset_pw) {
+-                        reset_bv.bv_len = 1;
+-                        reset_bv.bv_val = "0";
++
++                    if (force_reset_pw || pwd_already_reset) {
++                        if (force_reset_pw) {
++                            reset_bv.bv_val = "0";
++                            reset_bv.bv_len = 1;
++                        } else if (pwd_already_reset) {
++                            /* Password was reset by the user, there is no
++                             * need to make the user change their password
++                             * again in AD so set pwdLastSet to -1 */
++                            reset_bv.bv_val = "-1";
++                            reset_bv.bv_len = 2;
++                        }
+                         reset_bvals[0] = &reset_bv;
+                         reset_bvals[1] = NULL;
+                         reset_pw_mod.mod_type = "pwdLastSet";
+@@ -807,7 +856,6 @@ send_password_modify(Slapi_DN *sdn,
+                     }
+ 
+                     pw_return = windows_conn_send_modify(prp->conn, slapi_sdn_get_dn(sdn), pw_mods, NULL, NULL);
+-
+                     slapi_ch_free((void **)&unicode_password);
+                 }
+                 PR_smprintf_free(quoted_password);
+diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c
+index ee3b00c3c..c2399e5c3 100644
+--- a/ldap/servers/plugins/schema_reload/schema_reload.c
++++ b/ldap/servers/plugins/schema_reload/schema_reload.c
+@@ -187,23 +187,6 @@ schemareload_thread(void *arg)
+                   "schemareload_thread <-- refcount decremented.\n");
+ }
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-    slapi_attr_first_value(attr, &val);
+-
+-    return slapi_value_get_string(val);
+-}
+-
+ static void
+ schemareload_destructor(Slapi_Task *task)
+ {
+diff --git a/ldap/servers/plugins/syntaxes/validate_task.c b/ldap/servers/plugins/syntaxes/validate_task.c
+index 2c625ba71..afec9ef7a 100644
+--- a/ldap/servers/plugins/syntaxes/validate_task.c
++++ b/ldap/servers/plugins/syntaxes/validate_task.c
+@@ -43,7 +43,6 @@ static int syntax_validate_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entr
+ static void syntax_validate_task_destructor(Slapi_Task *task);
+ static void syntax_validate_task_thread(void *arg);
+ static int syntax_validate_task_callback(Slapi_Entry *e, void *callback_data);
+-static const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
+ static void syntax_validate_set_plugin_id(void *plugin_id);
+ static void *syntax_validate_get_plugin_id(void);
+ 
+@@ -258,25 +257,6 @@ bail:
+     return rc;
+ }
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0) {
+-        return default_val;
+-    }
+-
+-    slapi_attr_first_value(attr, &val);
+-
+-    return slapi_value_get_string(val);
+-}
+-
+ /*
+  * Plug-in identity management helper functions
+  */
+diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
+index 4b75654e7..bdad4e59e 100644
+--- a/ldap/servers/slapd/slapi-plugin.h
++++ b/ldap/servers/slapd/slapi-plugin.h
+@@ -8294,6 +8294,8 @@ int32_t slapi_atomic_decr_32(int32_t *ptr, int memorder);
+  */
+ uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder);
+ 
++/* helper function */
++const char * fetch_attr(Slapi_Entry *e, const char *attrname, char *default_val);
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
+index 3f9d5d995..698ee19b9 100644
+--- a/ldap/servers/slapd/task.c
++++ b/ldap/servers/slapd/task.c
+@@ -80,7 +80,6 @@ static void destroy_task(time_t when, void *arg);
+ static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
+ static int task_deny(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
+ static void task_generic_destructor(Slapi_Task *task);
+-static const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
+ static Slapi_Entry *get_internal_entry(Slapi_PBlock *pb, char *dn);
+ static void modify_internal_entry(char *dn, LDAPMod **mods);
+ static void fixup_tombstone_task_destructor(Slapi_Task *task);
+@@ -684,22 +683,6 @@ destroy_task(time_t when, void *arg)
+     slapi_ch_free((void **)&task);
+ }
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-    slapi_attr_first_value(attr, &val);
+-    return slapi_value_get_string(val);
+-}
+-
+ /* supply the pblock, destroy it when you're done */
+ static Slapi_Entry *
+ get_internal_entry(Slapi_PBlock *pb, char *dn)
+diff --git a/ldap/servers/slapd/test-plugins/sampletask.c b/ldap/servers/slapd/test-plugins/sampletask.c
+index d04f21b3d..22d43dd48 100644
+--- a/ldap/servers/slapd/test-plugins/sampletask.c
++++ b/ldap/servers/slapd/test-plugins/sampletask.c
+@@ -116,22 +116,6 @@ task_sampletask_thread(void *arg)
+     slapi_task_finish(task, rv);
+ }
+ 
+-/* extract a single value from the entry (as a string) -- if it's not in the
+- * entry, the default will be returned (which can be NULL).
+- * you do not need to free anything returned by this.
+- */
+-static const char *
+-fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
+-{
+-    Slapi_Attr *attr;
+-    Slapi_Value *val = NULL;
+-
+-    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+-        return default_val;
+-    slapi_attr_first_value(attr, &val);
+-    return slapi_value_get_string(val);
+-}
+-
+ static void
+ task_sampletask_destructor(Slapi_Task *task)
+ {
+diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
+index cb46efb3d..8563c5d27 100644
+--- a/ldap/servers/slapd/util.c
++++ b/ldap/servers/slapd/util.c
+@@ -1579,3 +1579,20 @@ slapi_create_errormsg(
+         va_end(ap);
+     }
+ }
++
++/*
++ * Extract a single value from an entry (as a string) -- if it's not in the
++ * entry, the default will be returned (which can be NULL).  You do not need
++ * to free the returned string value.
++ */
++const char *
++fetch_attr(Slapi_Entry *e, const char *attrname, char *default_val)
++{
++    Slapi_Attr *attr;
++    Slapi_Value *val = NULL;
++
++    if (slapi_entry_attr_find(e, attrname, &attr) != 0)
++        return default_val;
++    slapi_attr_first_value(attr, &val);
++    return slapi_value_get_string(val);
++}
+-- 
+2.17.2
+
diff --git a/SOURCES/0015-Ticket-49915-fix-compiler-warnings.patch b/SOURCES/0015-Ticket-49915-fix-compiler-warnings.patch
new file mode 100644
index 0000000..4357858
--- /dev/null
+++ b/SOURCES/0015-Ticket-49915-fix-compiler-warnings.patch
@@ -0,0 +1,57 @@
+From b1cc97c13bbbcaa6a3c217d285283203809fa90b Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Tue, 16 Oct 2018 10:49:29 +0200
+Subject: [PATCH] Ticket 49915 - fix compiler warnings
+
+---
+ ldap/servers/slapd/back-ldbm/idl_new.c | 2 +-
+ ldap/servers/slapd/back-ldbm/index.c   | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
+index 102265c47..81172f590 100644
+--- a/ldap/servers/slapd/back-ldbm/idl_new.c
++++ b/ldap/servers/slapd/back-ldbm/idl_new.c
+@@ -379,7 +379,7 @@ idl_new_range_fetch(
+             bck_info.index = SLAPI_ATTR_PARENTID;
+             bck_info.key = "0";
+ 
+-            if (rc = slapi_back_get_info(be, BACK_INFO_INDEX_KEY, (void **)&bck_info)) {
++            if ((rc = slapi_back_get_info(be, BACK_INFO_INDEX_KEY, (void **)&bck_info))) {
+                 slapi_log_err(SLAPI_LOG_WARNING, "idl_new_range_fetch", "Total update: fail to retrieve suffix entryID, continue assuming it is the first entry\n");
+             }
+             if (bck_info.key_found) {
+diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c
+index dea6e9a3e..f0b969ff4 100644
+--- a/ldap/servers/slapd/back-ldbm/index.c
++++ b/ldap/servers/slapd/back-ldbm/index.c
+@@ -1262,7 +1262,7 @@ set_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info)
+     /* Start a txn */
+     li = (struct ldbminfo *)be->be_database->plg_private;
+     dblayer_txn_init(li, &txn);
+-    if (rc = dblayer_txn_begin(be, txn.back_txn_txn, &txn)) {
++    if ((rc = dblayer_txn_begin(be, txn.back_txn_txn, &txn))) {
+         slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): txn begin fails\n",
+                   info->index, info->key, info->id);
+         return rc;
+@@ -1272,7 +1272,7 @@ set_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info)
+     sv_key[1] = NULL;
+     slapi_value_init_string(sv_key[0], info->key);
+ 
+-    if (rc = index_addordel_values_sv(be, info->index, sv_key, NULL, info->id, BE_INDEX_ADD, &txn)) {
++    if ((rc = index_addordel_values_sv(be, info->index, sv_key, NULL, info->id, BE_INDEX_ADD, &txn))) {
+         value_done(sv_key[0]);
+         dblayer_txn_abort(be, &txn);
+         slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): index_addordel_values_sv fails\n",
+@@ -1281,7 +1281,7 @@ set_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info)
+     }
+ 
+     value_done(sv_key[0]);
+-    if (rc = dblayer_txn_commit(be, &txn)) {
++    if ((rc = dblayer_txn_commit(be, &txn))) {
+         slapi_log_err(SLAPI_LOG_ERR, "set_suffix_key", "Fail to update %s index with  %s/%d (key/ID): commit fails\n",
+                   info->index, info->key, info->id);
+         return rc;
+-- 
+2.17.2
+
diff --git a/SOURCES/0016-Ticket-49915-fix-compiler-warnings-2nd.patch b/SOURCES/0016-Ticket-49915-fix-compiler-warnings-2nd.patch
new file mode 100644
index 0000000..ce463a8
--- /dev/null
+++ b/SOURCES/0016-Ticket-49915-fix-compiler-warnings-2nd.patch
@@ -0,0 +1,25 @@
+From 309b90041dcaa2ddc1931dddea0827cef0cbb9bf Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Tue, 16 Oct 2018 15:06:38 +0200
+Subject: [PATCH] Ticket 49915 - fix compiler warnings (2nd)
+
+---
+ ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+index a3241b078..61c3313c5 100644
+--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
++++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+@@ -305,6 +305,8 @@ int index_buffer_init(size_t size, int flags, void **h);
+ int index_buffer_flush(void *h, backend *be, DB_TXN *txn, struct attrinfo *a);
+ int index_buffer_terminate(void *h);
+ 
++int get_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info);
++int set_suffix_key(Slapi_Backend *be, struct _back_info_index_key *info);
+ char *index_index2prefix(const char *indextype);
+ void index_free_prefix(char *);
+ 
+-- 
+2.17.2
+
diff --git a/SOURCES/0017-Ticket-49618-Increase-cachememsize-and-dncachememsize.patch b/SOURCES/0017-Ticket-49618-Increase-cachememsize-and-dncachememsize.patch
new file mode 100644
index 0000000..7b4ae87
--- /dev/null
+++ b/SOURCES/0017-Ticket-49618-Increase-cachememsize-and-dncachememsize.patch
@@ -0,0 +1,51 @@
+From 60c0e7dfb30fbd8100d45e79d11141956f51656f Mon Sep 17 00:00:00 2001
+From: Simon Pichugin <spichugi@redhat.com>
+Date: Fri, 14 Dec 2018 17:34:34 +0100
+Subject: [PATCH] Issue 49618 - Increase cachememsize and dncachememsize
+ variable sizes
+
+Description: nssapld-cachememsize is reverted to a smaller value
+if the cap is reached. Increase it to UINT64.
+
+https://pagure.io/389-ds-base/issue/49618
+
+Reviewed by: tbordaz, mreynolds (Thanks!)
+---
+ ldap/servers/slapd/back-ldbm/ldbm_config.c          | 2 +-
+ ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
+index 4e1a94341..144c5efc5 100644
+--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
++++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
+@@ -2118,7 +2118,7 @@ ldbm_config_get(void *arg, config_info *config, char *buf)
+         break;
+     case CONFIG_TYPE_SIZE_T:
+         val = (size_t)config->config_get_fn(arg);
+-        sprintf(buf, "%lu", (long unsigned int)val);
++        sprintf(buf, "%" PRIu32, (uint32_t)val);
+         break;
+     case CONFIG_TYPE_UINT64:
+         val = (uint64_t)((uintptr_t)config->config_get_fn(arg));
+diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+index 643628c85..5eac1c1df 100644
+--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
++++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+@@ -366,11 +366,11 @@ ldbm_instance_config_require_index_set(void *arg,
+  *----------------------------------------------------------------------*/
+ static config_info ldbm_instance_config[] = {
+     {CONFIG_INSTANCE_CACHESIZE, CONFIG_TYPE_LONG, "-1", &ldbm_instance_config_cachesize_get, &ldbm_instance_config_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
+-    {CONFIG_INSTANCE_CACHEMEMSIZE, CONFIG_TYPE_SIZE_T, DEFAULT_CACHE_SIZE_STR, &ldbm_instance_config_cachememsize_get, &ldbm_instance_config_cachememsize_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
++    {CONFIG_INSTANCE_CACHEMEMSIZE, CONFIG_TYPE_UINT64, DEFAULT_CACHE_SIZE_STR, &ldbm_instance_config_cachememsize_get, &ldbm_instance_config_cachememsize_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
+     {CONFIG_INSTANCE_READONLY, CONFIG_TYPE_ONOFF, "off", &ldbm_instance_config_readonly_get, &ldbm_instance_config_readonly_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
+     {CONFIG_INSTANCE_REQUIRE_INDEX, CONFIG_TYPE_ONOFF, "off", &ldbm_instance_config_require_index_get, &ldbm_instance_config_require_index_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
+     {CONFIG_INSTANCE_DIR, CONFIG_TYPE_STRING, NULL, &ldbm_instance_config_instance_dir_get, &ldbm_instance_config_instance_dir_set, CONFIG_FLAG_ALWAYS_SHOW},
+-    {CONFIG_INSTANCE_DNCACHEMEMSIZE, CONFIG_TYPE_SIZE_T, DEFAULT_DNCACHE_SIZE_STR, &ldbm_instance_config_dncachememsize_get, &ldbm_instance_config_dncachememsize_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
++    {CONFIG_INSTANCE_DNCACHEMEMSIZE, CONFIG_TYPE_UINT64, DEFAULT_DNCACHE_SIZE_STR, &ldbm_instance_config_dncachememsize_get, &ldbm_instance_config_dncachememsize_set, CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
+     {NULL, 0, NULL, NULL, NULL, 0}};
+ 
+ void
+-- 
+2.17.2
+
diff --git a/SOURCES/0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch b/SOURCES/0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch
new file mode 100644
index 0000000..bd10630
--- /dev/null
+++ b/SOURCES/0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch
@@ -0,0 +1,209 @@
+From 70fd6e1fa6667734f39146cef53de6e3ff22d765 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Fri, 9 Nov 2018 17:07:11 +0100
+Subject: [PATCH] Ticket 50020 - during MODRDN referential integrity can fail
+ erronously while updating large groups
+
+Bug Description:
+	During a MODRDN of a group member, referential integrity will update the groups containing this member.
+	Under specific conditions, the MODRDN can fail (err=1).
+
+	on MODRDN Referential integrity checks if the original DN of the target MODRDN entry is
+	member of a given group. If it is then it updates the group.
+	The returned code of the group update is using the variable 'rc'.
+	It does a normalized DN comparison to compare original DN with members DN, to determine if
+	a group needs to be updated.
+	If the group does not need to be updated, 'rc' is not set.
+	The bug is that it uses 'rc' to normalize the DN and if the group is not updated
+	the returned code reflects the normalization returned code rather that the group update.
+
+	The bug is hit in specific conditions
+
+	    One of the evaluated group contains more than 128 members
+	    the last member (last value) of the group is not the moved entry
+	    the last member (last value) of the group is a DN value that contains escaped chars
+
+Fix Description:
+	Use a local variable to check the result of the DN normalization
+
+https://pagure.io/389-ds-base/issue/50020
+
+Reviewed by: Simon Pichugin, Mark Reynolds (thanks)
+
+Platforms tested: F27
+
+Flag Day: no
+---
+ .../tests/suites/plugins/referint_test.py     | 103 ++++++++++++++++++
+ ldap/servers/plugins/referint/referint.c      |  18 +--
+ 2 files changed, 113 insertions(+), 8 deletions(-)
+ create mode 100644 dirsrvtests/tests/suites/plugins/referint_test.py
+
+diff --git a/dirsrvtests/tests/suites/plugins/referint_test.py b/dirsrvtests/tests/suites/plugins/referint_test.py
+new file mode 100644
+index 000000000..67a11de9e
+--- /dev/null
++++ b/dirsrvtests/tests/suites/plugins/referint_test.py
+@@ -0,0 +1,103 @@
++# --- BEGIN COPYRIGHT BLOCK ---
++# Copyright (C) 2016 Red Hat, Inc.
++# All rights reserved.
++#
++# License: GPL (version 3 or any later version).
++# See LICENSE for details.
++# --- END COPYRIGHT BLOCK ---
++#
++'''
++Created on Dec 12, 2019
++
++@author: tbordaz
++'''
++import logging
++import subprocess
++import pytest
++from lib389 import Entry
++from lib389.utils import *
++from lib389.plugins import *
++from lib389._constants import *
++from lib389.idm.user import UserAccounts, UserAccount
++from lib389.idm.group import Groups
++from lib389.topologies import topology_st as topo
++
++log = logging.getLogger(__name__)
++
++ESCAPED_RDN_BASE = "foo\,oo"
++def _user_get_dn(no):
++    uid = '%s%d' % (ESCAPED_RDN_BASE, no)
++    dn = 'uid=%s,%s' % (uid, SUFFIX)
++    return (uid, dn)
++
++def add_escaped_user(server, no):
++    (uid, dn) = _user_get_dn(no)
++    log.fatal('Adding user (%s): ' % dn)
++    server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
++                             'uid': [uid],
++                             'sn' : [uid],
++                             'cn' : [uid]})))
++    return dn
++
++@pytest.mark.ds50020
++def test_referential_false_failure(topo):
++    """On MODRDN referential integrity can erronously fail
++
++    :id: f77aeb80-c4c4-471b-8c1b-4733b714778b
++    :setup: Standalone Instance
++    :steps:
++        1. Configure the plugin
++        2. Create a group
++            - 1rst member the one that will be move
++            - more than 128 members
++            - last member is a DN containing escaped char
++        3. Rename the 1rst member
++    :expectedresults:
++        1. should succeed
++        2. should succeed
++        3. should succeed
++    """
++
++    inst = topo[0]
++
++    # stop the plugin, and start it
++    plugin = ReferentialIntegrityPlugin(inst)
++    plugin.disable()
++    plugin.enable()
++
++    ############################################################################
++    # Configure plugin
++    ############################################################################
++    GROUP_CONTAINER = "ou=groups,%s" % DEFAULT_SUFFIX
++    plugin.replace('referint-membership-attr', 'member')
++    plugin.replace('nsslapd-plugincontainerscope', GROUP_CONTAINER)
++
++    ############################################################################
++    # Creates a group with members having escaped DN
++    ############################################################################
++    # Add some users and a group
++    users = UserAccounts(inst, DEFAULT_SUFFIX, None)
++    user1 = users.create_test_user(uid=1001)
++    user2 = users.create_test_user(uid=1002)
++
++    groups = Groups(inst, GROUP_CONTAINER, None)
++    group = groups.create(properties={'cn': 'group'})
++    group.add('member', user2.dn)
++    group.add('member', user1.dn)
++
++    # Add more than 128 members so that referint follows the buggy path
++    for i in range(130):
++        escaped_user = add_escaped_user(inst, i)
++        group.add('member', escaped_user)
++
++    ############################################################################
++    # Check that the MODRDN succeeds
++    ###########################################################################
++    # Here we need to restart so that member values are taken in the right order
++    # the last value is the escaped one
++    inst.restart()
++
++    # Here if the bug is fixed, referential is able to update the member value
++    inst.rename_s(user1.dn, 'uid=new_test_user_1001', newsuperior=SUFFIX, delold=0)
++
++
+diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
+index f6d1c27a2..9e4e680d3 100644
+--- a/ldap/servers/plugins/referint/referint.c
++++ b/ldap/servers/plugins/referint/referint.c
+@@ -824,20 +824,21 @@ _update_one_per_mod(Slapi_DN *entrySDN, /* DN of the searched entry */
+          */
+         for (nval = slapi_attr_first_value(attr, &v); nval != -1;
+              nval = slapi_attr_next_value(attr, nval, &v)) {
++            int normalize_rc;
+             p = NULL;
+             dnlen = 0;
+ 
+             /* DN syntax, which should be a string */
+             sval = slapi_ch_strdup(slapi_value_get_string(v));
+-            rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+-            if (rc == 0) { /* sval is passed in; not terminated */
++            normalize_rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
++            if (normalize_rc == 0) { /* sval is passed in; not terminated */
+                 *(p + dnlen) = '\0';
+                 sval = p;
+-            } else if (rc > 0) {
++            } else if (normalize_rc > 0) {
+                 slapi_ch_free_string(&sval);
+                 sval = p;
+             }
+-            /* else: (rc < 0) Ignore the DN normalization error for now. */
++            /* else: (normalize_rc < 0) Ignore the DN normalization error for now. */
+ 
+             p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
+             if (p == sval) {
+@@ -1013,20 +1014,21 @@ _update_all_per_mod(Slapi_DN *entrySDN, /* DN of the searched entry */
+         for (nval = slapi_attr_first_value(attr, &v);
+              nval != -1;
+              nval = slapi_attr_next_value(attr, nval, &v)) {
++            int normalize_rc;
+             p = NULL;
+             dnlen = 0;
+ 
+             /* DN syntax, which should be a string */
+             sval = slapi_ch_strdup(slapi_value_get_string(v));
+-            rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+-            if (rc == 0) { /* sval is passed in; not terminated */
++            normalize_rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
++            if (normalize_rc == 0) { /* sval is passed in; not terminated */
+                 *(p + dnlen) = '\0';
+                 sval = p;
+-            } else if (rc > 0) {
++            } else if (normalize_rc > 0) {
+                 slapi_ch_free_string(&sval);
+                 sval = p;
+             }
+-            /* else: (rc < 0) Ignore the DN normalization error for now. */
++            /* else: normalize_rc < 0) Ignore the DN normalization error for now. */
+ 
+             p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
+             if (p == sval) {
+-- 
+2.17.2
+
diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec
index cc73e59..200a9de 100644
--- a/SPECS/389-ds-base.spec
+++ b/SPECS/389-ds-base.spec
@@ -39,7 +39,7 @@
 Summary:          389 Directory Server (%{variant})
 Name:             389-ds-base
 Version:          1.3.8.4
-Release:          %{?relprefix}18%{?prerel}%{?dist}
+Release:          %{?relprefix}22%{?prerel}%{?dist}
 License:          GPLv3+
 URL:              https://www.port389.org/
 Group:            System Environment/Daemons
@@ -159,6 +159,13 @@ Patch09:          0009-Bug-1624004-fix-regression-in-empty-attribute-list.patch
 Patch10:          0010-Ticket-49968-Confusing-CRITICAL-message-list_candida.patch
 Patch11:          0011-Ticket-49967-entry-cache-corruption-after-failed-MOD.patch
 Patch12:          0012-Ticket-49958-extended-search-fail-to-match-entries.patch
+Patch13:          0013-Ticket-49915-Master-ns-slapd-had-100-CPU-usage-after.patch
+Patch14:          0014-Ticket-49950-PassSync-not-setting-pwdLastSet-attribu.patch
+Patch15:          0015-Ticket-49915-fix-compiler-warnings.patch
+Patch16:          0016-Ticket-49915-fix-compiler-warnings-2nd.patch
+Patch17:          0017-Ticket-49618-Increase-cachememsize-and-dncachememsize.patch
+Patch21:          0018-Ticket-50020-during-MODRDN-referential-integrity-can.patch
+
 
 %description
 389 Directory Server is an LDAPv3 compliant server.  The base package includes
@@ -507,6 +514,24 @@ fi
 %{_sysconfdir}/%{pkgname}/dirsrvtests
 
 %changelog
+* Mon Dec 17 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.8.4-22
+- Bump version to 1.3.8.4-22
+- Resolves: Bug 1660120 - certmap fails when Issuer DN has comma in name
+
+* Mon Dec 17 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.8.4-21
+- Bump version to 1.3.8.4-21
+- Resolves: Bug 1659510 - during MODRDN referential integrity can fail erronously while updating large groups
+- Resolves: Bug 1659936 - After RHEL 7.6 HTB update, unable to set nsslapd-cachememsize (RHDS 10) to custom value
+
+* Tue Dec 4 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.8.4-20
+- Bump version to 1.3.8.4-20
+- Resolves: Bug 1645197 - Fix compiler warnings
+
+* Tue Dec 4 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.8.4-19
+- Bump version to 1.3.8.4-19
+- Resolves: Bug 1653820 - PassSync not setting pwdLastSet attribute in Active Directory after Pw update from LDAP sync for normal user
+- Resolves: Bug 1645197 - on-line re-initialization hangs
+
 * Mon Oct 29 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.8.4-18
 - Bump version to 1.3.8.4-18
 - Resolves: Bug 1638516 - CRIT - list_candidates - NULL idl was recieved from filter_candidates_ex