diff --git a/SOURCES/0061-Ticket-49080-shadowExpire-should-not-be-a-calculated.patch b/SOURCES/0061-Ticket-49080-shadowExpire-should-not-be-a-calculated.patch
new file mode 100644
index 0000000..c2a40e3
--- /dev/null
+++ b/SOURCES/0061-Ticket-49080-shadowExpire-should-not-be-a-calculated.patch
@@ -0,0 +1,100 @@
+From 50b73af8729b6753c71ba6206632561b5974523d Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@redhat.com>
+Date: Wed, 11 Jan 2017 14:14:40 -0800
+Subject: [PATCH 61/67] Ticket #49080 - shadowExpire should not be a calculated
+ value
+
+Description: Reverting the changes made on shadowExpire in the ticket 548.
+
+Thanks to Gordon Messmer (gordon.messmer@gmail.com) for providing the original patch.
+
+Reviewed by William Brown <wibrown@redhat.com> (Thanks!!).
+
+(cherry picked from commit 14eb192b0f99ae3d811fd8a5bb40713bc85ea533)
+(cherry picked from commit 2ca12fc5b79dbbb8889eba6da7b4ce59cd6cb86d)
+---
+ ldap/servers/slapd/pw.c | 29 +++++------------------------
+ 1 file changed, 5 insertions(+), 24 deletions(-)
+
+diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
+index 6f02f90..ce1ca2a 100644
+--- a/ldap/servers/slapd/pw.c
++++ b/ldap/servers/slapd/pw.c
+@@ -2803,7 +2803,6 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+     const char *dn = NULL;
+     passwdPolicy *pwpolicy = NULL;
+     long long shadowval = 0;
+-    long long exptime = 0;
+     Slapi_Mods *smods = NULL;
+     LDAPMod **mods;
+     long long sval;
+@@ -2811,7 +2810,6 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+     char *shmin = NULL;
+     char *shmax = NULL;
+     char *shwarn = NULL;
+-    char *shexp = NULL;
+     int rc = 0;
+ 
+     if (!e || !*e) {
+@@ -2861,7 +2859,6 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+     /* shadowMax - the maximum number of days for which the user password remains valid. */
+     if (pwpolicy->pw_maxage > 0) {
+         shadowval = pwpolicy->pw_maxage / _SEC_PER_DAY;
+-        exptime = time_plus_sec(current_time(), pwpolicy->pw_maxage);
+         if (shadowval > _MAX_SHADOW) {
+             shadowval = _MAX_SHADOW;
+         }
+@@ -2903,22 +2900,6 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+         shwarn = slapi_ch_smprintf("%lld", shadowval);
+     }
+ 
+-    /* shadowExpire - the date on which the user login will be disabled. */
+-    if (exptime) {
+-        shexp = slapi_entry_attr_get_charptr(*e, "shadowExpire");
+-        exptime /= _SEC_PER_DAY;
+-        if (shexp) {
+-            sval = strtoll(shexp, NULL, 0);
+-            if (sval != exptime) {
+-                slapi_ch_free_string(&shexp);
+-                shexp = slapi_ch_smprintf("%lld", exptime);
+-                mod_num++;
+-            }
+-        } else {
+-            mod_num++;
+-            shexp = slapi_ch_smprintf("%lld", exptime);
+-        }
+-    }
+     smods = slapi_mods_new();
+     slapi_mods_init(smods, mod_num);
+     if (shmin) {
+@@ -2933,10 +2914,6 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+         slapi_mods_add(smods, LDAP_MOD_REPLACE, "shadowWarning", strlen(shwarn), shwarn);
+         slapi_ch_free_string(&shwarn);
+     }
+-    if (shexp) {
+-        slapi_mods_add(smods, LDAP_MOD_REPLACE, "shadowExpire", strlen(shexp), shexp);
+-        slapi_ch_free_string(&shexp);
+-    }
+     /* Apply the  mods to create the resulting entry. */
+     mods = slapi_mods_get_ldapmods_byref(smods);
+     if (mods) {
+@@ -2947,11 +2924,15 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+     }
+     slapi_mods_free(&smods);
+ 
+-#if 0 /* These 2 attributes are no need (or not able) to auto-fill. */
++#if 0 /* These 3 attributes are no need (or not able) to auto-fill. */
+     /* 
+      * shadowInactive - the number of days of inactivity allowed for the user.
+      * Password Policy does not have the corresponding parameter.
+      * 
++     * shadowExpire - the number of days since Jan 1, 1970 after which the
++     * account, not the password, will expire.  This is not affected by the
++     * Password Policy.
++     * 
+      * shadowFlag - not currently in use.
+      */
+ #endif
+-- 
+2.9.3
+
diff --git a/SOURCES/0062-Ticket-49082-Fix-password-expiration-related-shadow-.patch b/SOURCES/0062-Ticket-49082-Fix-password-expiration-related-shadow-.patch
new file mode 100644
index 0000000..c00b4d3
--- /dev/null
+++ b/SOURCES/0062-Ticket-49082-Fix-password-expiration-related-shadow-.patch
@@ -0,0 +1,145 @@
+From 96ad7ec4fa84dd32439e3473c0128612dd5f9d49 Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@redhat.com>
+Date: Wed, 11 Jan 2017 15:04:42 -0800
+Subject: [PATCH 62/67] Ticket #49082 - Fix password expiration related shadow
+ attributes
+
+The original patch was provided by Gordon Messmer (gordon.messmer@gmail.com)
+with the description:
+  Bug description:
+  Shadow attributes (in /etc/shadow and in LDAP) are typically unset when no
+  policy is in place. 389-ds will incorrectly return values (possibly set to 0)
+  when there is no policy.
+
+  Fix description:
+  Only auto-fill shadow attributes when a password policy is available.  These
+  are empty when no policy is in place.
+
+  Don't auto-fill expiration related shadow attributes if passwords never expire.
+
+Reviewed by William Brown <wibrown@redhat.com> (Thanks!!).
+
+(cherry picked from commit 5bcd966b73708f6b558f01e6b11a7a11e8d3b126)
+(cherry picked from commit faae0fa5a4a6b3d590c1a9e068d9436965cc49c9)
+---
+ ldap/servers/slapd/pw.c | 74 +++++++++++++++++++++++++------------------------
+ 1 file changed, 38 insertions(+), 36 deletions(-)
+
+diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
+index ce1ca2a..30a2cb9 100644
+--- a/ldap/servers/slapd/pw.c
++++ b/ldap/servers/slapd/pw.c
+@@ -2802,7 +2802,7 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+ {
+     const char *dn = NULL;
+     passwdPolicy *pwpolicy = NULL;
+-    long long shadowval = 0;
++    long long shadowval = -1;
+     Slapi_Mods *smods = NULL;
+     LDAPMod **mods;
+     long long sval;
+@@ -2840,64 +2840,66 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e)
+         if (shadowval > _MAX_SHADOW) {
+             shadowval = _MAX_SHADOW;
+         }
+-    } else {
+-        shadowval = 0;
+     }
+-    shmin = slapi_entry_attr_get_charptr(*e, "shadowMin");
+-    if (shmin) {
+-        sval = strtoll(shmin, NULL, 0);
+-        if (sval != shadowval) {
+-            slapi_ch_free_string(&shmin);
+-            shmin = slapi_ch_smprintf("%lld", shadowval);
++    if (shadowval > 0) {
++        shmin = slapi_entry_attr_get_charptr(*e, "shadowMin");
++        if (shmin) {
++            sval = strtoll(shmin, NULL, 0);
++            if (sval != shadowval) {
++                slapi_ch_free_string(&shmin);
++                shmin = slapi_ch_smprintf("%lld", shadowval);
++                mod_num++;
++            }
++        } else {
+             mod_num++;
++            shmin = slapi_ch_smprintf("%lld", shadowval);
+         }
+-    } else {
+-        mod_num++;
+-        shmin = slapi_ch_smprintf("%lld", shadowval);
+     }
+ 
+     /* shadowMax - the maximum number of days for which the user password remains valid. */
+-    if (pwpolicy->pw_maxage > 0) {
++    shadowval = -1;
++    if (pwpolicy->pw_exp == 1 && pwpolicy->pw_maxage > 0) {
+         shadowval = pwpolicy->pw_maxage / _SEC_PER_DAY;
+         if (shadowval > _MAX_SHADOW) {
+             shadowval = _MAX_SHADOW;
+         }
+-    } else {
+-        shadowval = _MAX_SHADOW;
+     }
+-    shmax = slapi_entry_attr_get_charptr(*e, "shadowMax");
+-    if (shmax) {
+-        sval = strtoll(shmax, NULL, 0);
+-        if (sval != shadowval) {
+-            slapi_ch_free_string(&shmax);
+-            shmax = slapi_ch_smprintf("%lld", shadowval);
++    if (shadowval > 0) {
++        shmax = slapi_entry_attr_get_charptr(*e, "shadowMax");
++        if (shmax) {
++            sval = strtoll(shmax, NULL, 0);
++            if (sval != shadowval) {
++                slapi_ch_free_string(&shmax);
++                shmax = slapi_ch_smprintf("%lld", shadowval);
++                mod_num++;
++            }
++        } else {
+             mod_num++;
++            shmax = slapi_ch_smprintf("%lld", shadowval);
+         }
+-    } else {
+-        mod_num++;
+-        shmax = slapi_ch_smprintf("%lld", shadowval);
+     }
+ 
+     /* shadowWarning - the number of days of advance warning given to the user before the user password expires. */
+-    if (pwpolicy->pw_warning > 0) {
++    shadowval = -1;
++    if (pwpolicy->pw_exp == 1 && pwpolicy->pw_warning > 0) {
+         shadowval = pwpolicy->pw_warning / _SEC_PER_DAY;
+         if (shadowval > _MAX_SHADOW) {
+             shadowval = _MAX_SHADOW;
+         }
+-    } else {
+-        shadowval = 0;
+     }
+-    shwarn = slapi_entry_attr_get_charptr(*e, "shadowWarning");
+-    if (shwarn) {
+-        sval = strtoll(shwarn, NULL, 0);
+-        if (sval != shadowval) {
+-            slapi_ch_free_string(&shwarn);
+-            shwarn = slapi_ch_smprintf("%lld", shadowval);
++    if (shadowval > 0) {
++        shwarn = slapi_entry_attr_get_charptr(*e, "shadowWarning");
++        if (shwarn) {
++            sval = strtoll(shwarn, NULL, 0);
++            if (sval != shadowval) {
++                slapi_ch_free_string(&shwarn);
++                shwarn = slapi_ch_smprintf("%lld", shadowval);
++                mod_num++;
++            }
++        } else {
+             mod_num++;
++            shwarn = slapi_ch_smprintf("%lld", shadowval);
+         }
+-    } else {
+-        mod_num++;
+-        shwarn = slapi_ch_smprintf("%lld", shadowval);
+     }
+ 
+     smods = slapi_mods_new();
+-- 
+2.9.3
+
diff --git a/SOURCES/0063-Ticket-49082-Adjusted-the-CI-test-case-to-the-fix.patch b/SOURCES/0063-Ticket-49082-Adjusted-the-CI-test-case-to-the-fix.patch
new file mode 100644
index 0000000..97fb5d1
--- /dev/null
+++ b/SOURCES/0063-Ticket-49082-Adjusted-the-CI-test-case-to-the-fix.patch
@@ -0,0 +1,33 @@
+From ee9b5c5dc3f4382ee73abefb9d2e3c275e62d6c8 Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@redhat.com>
+Date: Wed, 11 Jan 2017 15:14:07 -0800
+Subject: [PATCH 63/67] Ticket #49082 - Adjusted the CI test case to the fix.
+
+Description: Fix password expiration related shadow attributes
+(cherry picked from commit 5a6a5a18d0458bd147af57a06158245f329ddba3)
+(cherry picked from commit b9e565df5d304ba9fb516b987ad62480590a5845)
+---
+ dirsrvtests/tests/tickets/ticket548_test.py | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/dirsrvtests/tests/tickets/ticket548_test.py b/dirsrvtests/tests/tickets/ticket548_test.py
+index d29fa53..dea7c3c 100644
+--- a/dirsrvtests/tests/tickets/ticket548_test.py
++++ b/dirsrvtests/tests/tickets/ticket548_test.py
+@@ -98,6 +98,13 @@ def set_global_pwpolicy(topology, min_=1, max_=10, warn=3):
+         log.error('Failed to set passwordMinAge: error ' + e.message['desc'])
+         assert False
+ 
++    log.info("		Set global password Expiration -- on\n")
++    try:
++        topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordExp', 'on')])
++    except ldap.LDAPError as e:
++        log.error('Failed to set passwordExp: error ' + e.message['desc'])
++        assert False
++
+     log.info("		Set global password Max Age -- %s days\n" % max_)
+     try:
+         topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMaxAge', '%s' % max_secs)])
+-- 
+2.9.3
+
diff --git a/SOURCES/0064-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch b/SOURCES/0064-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
new file mode 100644
index 0000000..32d1bbb
--- /dev/null
+++ b/SOURCES/0064-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
@@ -0,0 +1,631 @@
+From d1477e4a03d85aec79b497db4531d9e484029139 Mon Sep 17 00:00:00 2001
+From: Ludwig Krispenz <lkrispen@redhat.com>
+Date: Tue, 24 Jan 2017 15:07:19 +0100
+Subject: [PATCH 64/67]     Ticket 49008 backport 1.3.5 : aborted operation can
+ leave RUV in incorrect state
+
+        Bug description:
+        If a plugin operation succeeded, but the operation itself fails and is aborted the RUV is in an incorrect state (rolled up to the succesful plugin op)
+
+        Fix Decription:
+        Introduce a "primary_csn", this is the csn of the main operation, either a client operation or a replicated operation.
+        csns generated by internal operations, eg by plugins are secondary csn.
+
+        Maintain the primary csn in thread local data, like it is used for the agreement name (or txn stack): prim_csn.
+
+        Extend the data structure of the pending list to keep prim_csn for each inserted csn
+
+        If a csn is created or received check prim_csn: if it exists use it, if it doesn't exist set it
+
+        when inserting a csn to the pending list pass the prim_csn
+
+        when cancelling a csn, if it is the prim_csn also cancell all secondary csns
+
+        when committing a csn,
+
+        if it is not the primary csn, do nothing
+
+        if it is the prim_csn trigger the pending list rollup, stop at the first not committed csn
+
+        if the RID of the prim_csn is not the local RID also rollup the pending list for the local RID.
+
+        Reviewed by:  Thierry, Thanks
+
+(cherry picked from commit 79a3deafe943a3ce5c31c50272939146d17bd7ac)
+---
+ ldap/servers/plugins/replication/csnpl.c         | 75 +++++++++++++++++++++---
+ ldap/servers/plugins/replication/csnpl.h         |  5 +-
+ ldap/servers/plugins/replication/repl5.h         |  2 +
+ ldap/servers/plugins/replication/repl5_init.c    | 22 +++++++
+ ldap/servers/plugins/replication/repl5_plugins.c | 40 ++++++++-----
+ ldap/servers/plugins/replication/repl5_replica.c |  6 +-
+ ldap/servers/plugins/replication/repl5_ruv.c     | 74 +++++++++++++++++------
+ ldap/servers/plugins/replication/repl5_ruv.h     |  4 +-
+ ldap/servers/slapd/csn.c                         | 15 +++++
+ ldap/servers/slapd/slapi-private.h               |  2 +
+ 10 files changed, 195 insertions(+), 50 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/csnpl.c b/ldap/servers/plugins/replication/csnpl.c
+index acd38d0..db1ae13 100644
+--- a/ldap/servers/plugins/replication/csnpl.c
++++ b/ldap/servers/plugins/replication/csnpl.c
+@@ -24,8 +24,9 @@ struct csnpl
+ 
+ typedef struct _csnpldata
+ {
+-	PRBool		committed;  /* True if CSN committed */
+-	CSN			*csn;       /* The actual CSN */
++	PRBool	committed;  /* True if CSN committed */
++	CSN	*csn;       /* The actual CSN */
++	const CSN *prim_csn;  /* The primary CSN of an operation consising of multiple sub ops*/
+ } csnpldata;
+ 
+ /* forward declarations */
+@@ -103,7 +104,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)
++int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn)
+ {
+ 	int rc;
+ 	csnpldata *csnplnode;
+@@ -131,6 +132,7 @@ int csnplInsert (CSNPL *csnpl, const CSN *csn)
+ 	csnplnode = (csnpldata *)slapi_ch_malloc(sizeof(csnpldata));
+ 	csnplnode->committed = PR_FALSE;
+ 	csnplnode->csn = csn_dup(csn);
++	csnplnode->prim_csn = prim_csn;
+ 	csn_as_string(csn, PR_FALSE, csn_str);
+ 	rc = llistInsertTail (csnpl->csnList, csn_str, csnplnode);
+ 
+@@ -186,6 +188,57 @@ int csnplRemove (CSNPL *csnpl, const CSN *csn)
+ 	return 0;
+ }
+ 
++int csnplRemoveAll (CSNPL *csnpl, const CSN *csn)
++{
++	csnpldata *data;
++	void *iterator;
++
++	slapi_rwlock_wrlock (csnpl->csnLock);
++	data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
++	while (NULL != data)
++	{
++		if (csn_is_equal(data->csn, csn) ||
++		    csn_is_equal(data->prim_csn, csn)) {
++			csnpldata_free(&data);
++			data = (csnpldata *)llistRemoveCurrentAndGetNext(csnpl->csnList, &iterator);
++		} else {
++			data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
++		}
++	}
++#ifdef DEBUG
++    _csnplDumpContentNoLock(csnpl, "csnplRemoveAll");
++#endif
++	slapi_rwlock_unlock (csnpl->csnLock);
++	return 0;
++}
++
++
++int csnplCommitAll (CSNPL *csnpl, const CSN *csn)
++{
++	csnpldata *data;
++	void *iterator;
++	char csn_str[CSN_STRSIZE];
++
++	csn_as_string(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);
++	data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
++	while (NULL != data)
++	{
++		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)) {
++			data->committed = PR_TRUE;
++		}
++		data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
++	}
++	slapi_rwlock_unlock (csnpl->csnLock);
++	return 0;
++}
++
+ int csnplCommit (CSNPL *csnpl, const CSN *csn)
+ {
+ 	csnpldata *data;
+@@ -276,13 +329,12 @@ csnplRollUp(CSNPL *csnpl, CSN **first_commited)
+ 	  *first_commited = NULL;
+ 	}
+ 	data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
+-	while (NULL != data)
++	while (NULL != data && data->committed)
+ 	{
+ 		if (NULL != largest_committed_csn && freeit)
+ 		{
+ 			csn_free(&largest_committed_csn);
+ 		}
+-		if (data->committed) {
+ 			freeit = PR_TRUE;
+ 			largest_committed_csn = data->csn; /* Save it */
+ 			if (first_commited && (*first_commited == NULL)) {
+@@ -294,9 +346,6 @@ csnplRollUp(CSNPL *csnpl, CSN **first_commited)
+ 			data->csn = NULL;
+ 			csnpldata_free(&data);
+ 			data = (csnpldata *)llistRemoveCurrentAndGetNext(csnpl->csnList, &iterator);
+-		} else {
+-			data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
+-		}
+ 	} 
+ 
+ #ifdef DEBUG
+@@ -326,6 +375,7 @@ static void _csnplDumpContentNoLock(CSNPL *csnpl, const char *caller)
+     csnpldata *data;
+     void *iterator;
+     char csn_str[CSN_STRSIZE];
++    char primcsn_str[CSN_STRSIZE];
+     
+     data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
+ 	if (data) {
+@@ -334,11 +384,18 @@ static void _csnplDumpContentNoLock(CSNPL *csnpl, const char *caller)
+ 	}
+     while (data)
+     {
+-        slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "%s, %s\n",                        
++        slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "%s,(prim %s), %s\n",
+                         csn_as_string(data->csn, PR_FALSE, csn_str),
++			data->prim_csn ? csn_as_string(data->prim_csn, PR_FALSE, primcsn_str) : " ",
+                         data->committed ? "committed" : "not committed");
+         data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
+     }
+ }
+ #endif
+ 
++/* wrapper around csn_free, to satisfy NSPR thread context API */
++void
++csnplFreeCSN (void *arg)
++{
++	csn_free((CSN **)&arg);
++}
+diff --git a/ldap/servers/plugins/replication/csnpl.h b/ldap/servers/plugins/replication/csnpl.h
+index 32e3ff7..f5c28f5 100644
+--- a/ldap/servers/plugins/replication/csnpl.h
++++ b/ldap/servers/plugins/replication/csnpl.h
+@@ -22,10 +22,13 @@ typedef struct csnpl CSNPL;
+ 
+ CSNPL* csnplNew ();
+ void csnplFree (CSNPL **csnpl);
+-int csnplInsert (CSNPL *csnpl, const CSN *csn);
++int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn);
+ int csnplRemove (CSNPL *csnpl, const CSN *csn);
++int csnplRemoveAll (CSNPL *csnpl, const CSN *csn);
++int csnplCommitAll (CSNPL *csnpl, const CSN *csn);
+ CSN* csnplGetMinCSN (CSNPL *csnpl, PRBool *committed);
+ int csnplCommit (CSNPL *csnpl, const CSN *csn);
+ CSN *csnplRollUp(CSNPL *csnpl, CSN ** first);
+ void csnplDumpContent(CSNPL *csnpl, const char *caller); 
++
+ #endif
+diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
+index 4ab2355..27ad416 100644
+--- a/ldap/servers/plugins/replication/repl5.h
++++ b/ldap/servers/plugins/replication/repl5.h
+@@ -232,6 +232,8 @@ int multimaster_be_betxnpostop_modify (Slapi_PBlock *pb);
+ extern int repl5_is_betxn;
+ char* get_thread_private_agmtname ();
+ void  set_thread_private_agmtname (const char *agmtname);
++void  set_thread_primary_csn (const CSN *prim_csn);
++CSN*  get_thread_primary_csn(void);
+ void* get_thread_private_cache ();
+ void  set_thread_private_cache (void *buf);
+ char* get_repl_session_id (Slapi_PBlock *pb, char *id, CSN **opcsn);
+diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
+index 0304ed5..1570655 100644
+--- a/ldap/servers/plugins/replication/repl5_init.c
++++ b/ldap/servers/plugins/replication/repl5_init.c
+@@ -136,6 +136,7 @@ static int multimaster_started_flag = 0;
+ /* Thread private data and interface */
+ static PRUintn thread_private_agmtname;	/* thread private index for logging*/
+ static PRUintn thread_private_cache;
++static PRUintn thread_primary_csn;
+ 
+ char*
+ get_thread_private_agmtname()
+@@ -153,6 +154,26 @@ set_thread_private_agmtname(const char *agmtname)
+ 		PR_SetThreadPrivate(thread_private_agmtname, (void *)agmtname);
+ }
+ 
++CSN*
++get_thread_primary_csn(void)
++{
++	CSN *prim_csn = NULL;
++	if (thread_primary_csn)
++		prim_csn = (CSN *)PR_GetThreadPrivate(thread_primary_csn);
++	return prim_csn;
++}
++void
++set_thread_primary_csn(const CSN *prim_csn)
++{
++	if (thread_primary_csn) {
++		if (prim_csn) {
++			PR_SetThreadPrivate(thread_primary_csn, (void *)csn_dup(prim_csn));
++		} else {
++			PR_SetThreadPrivate(thread_primary_csn, NULL);
++		}
++	}
++}
++
+ void*
+ get_thread_private_cache ()
+ {
+@@ -721,6 +742,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);
+ 
+ 		/* 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 b331c81..84624e9 100644
+--- a/ldap/servers/plugins/replication/repl5_plugins.c
++++ b/ldap/servers/plugins/replication/repl5_plugins.c
+@@ -1033,9 +1033,11 @@ static int
+ write_changelog_and_ruv (Slapi_PBlock *pb)
+ {
+ 	Slapi_Operation *op = NULL;
++	CSN *opcsn;
++	CSN *prim_csn;
+ 	int rc;
+ 	slapi_operation_parameters *op_params = NULL;
+-	Object *repl_obj;
++	Object *repl_obj = NULL;
+ 	int return_value = SLAPI_PLUGIN_SUCCESS;
+ 	Replica *r;
+ 	Slapi_Backend *be;
+@@ -1063,17 +1065,17 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 	{
+ 		return return_value;
+ 	}
++	/* we only log changes for operations applied to a replica */
++	repl_obj = replica_get_replica_for_op (pb);
++	if (repl_obj == NULL)
++		return return_value;
+ 
+ 	slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
+ 	if (rc) { /* op failed - just return */
+-		return return_value;
++		cancel_opcsn(pb);
++		goto common_return;
+ 	}
+ 
+-	/* we only log changes for operations applied to a replica */
+-	repl_obj = replica_get_replica_for_op (pb);
+-	if (repl_obj == NULL)
+-		return return_value;
+- 
+ 	r = (Replica*)object_get_data (repl_obj);
+ 	PR_ASSERT (r);
+ 
+@@ -1108,7 +1110,7 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 
+ 			slapi_pblock_get (pb, SLAPI_OPERATION_PARAMETERS, &op_params);
+ 			if (NULL == op_params) {
+-				return return_value;
++				goto common_return;
+ 			}
+ 
+ 			/* need to set uniqueid operation parameter */
+@@ -1127,19 +1129,18 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 				slapi_pblock_get (pb, SLAPI_ENTRY_PRE_OP, &e);
+ 			}
+ 			if (NULL == e) {
+-				return return_value;
++				goto common_return;
+ 			}
+ 			uniqueid = slapi_entry_get_uniqueid (e);
+ 			if (NULL == uniqueid) {
+-				return return_value;
++				goto common_return;
+ 			}
+ 			op_params->target_address.uniqueid = slapi_ch_strdup (uniqueid);
+ 		} 
+ 
+ 		if( op_params->csn && is_cleaned_rid(csn_get_replicaid(op_params->csn))){
+ 			/* this RID has been cleaned */
+-			object_release (repl_obj);
+-			return return_value;
++			goto common_return;
+ 		}
+ 
+ 		/* we might have stripped all the mods - in that case we do not
+@@ -1152,7 +1153,7 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 			{
+ 				slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ 								"write_changelog_and_ruv: Skipped due to DISKFULL\n");
+-				return return_value;
++				goto common_return;
+ 			}
+ 			slapi_pblock_get(pb, SLAPI_TXN, &txn);
+ 			rc = cl5WriteOperationTxn(repl_name, repl_gen, op_params, 
+@@ -1188,7 +1189,6 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 	*/
+ 	if (0 == return_value) {
+ 		char csn_str[CSN_STRSIZE] = {'\0'};
+-		CSN *opcsn;
+ 		int rc;
+ 		const char *dn = op_params ? REPL_GET_DN(&op_params->target_address) : "unknown";
+ 		Slapi_DN *sdn = op_params ? (&op_params->target_address)->sdn : NULL;
+@@ -1220,7 +1220,15 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
+ 		}
+ 	}
+ 
+-	object_release (repl_obj);
++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 (repl_obj) {
++		object_release (repl_obj);
++	}
+ 	return return_value;
+ }
+ 
+@@ -1417,7 +1425,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);
++            ruv_cancel_csn_inprogress ((RUV*)object_get_data (ruv_obj), opcsn, replica_get_rid(r));
+             object_release (ruv_obj);
+         }
+ 
+diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
+index 7360d97..602653a 100644
+--- a/ldap/servers/plugins/replication/repl5_replica.c
++++ b/ldap/servers/plugins/replication/repl5_replica.c
+@@ -903,7 +903,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, rid == r->repl_rid);
++				rc = ruv_update_ruv (ruv, updated_csn, replica_purl, r->repl_rid);
+ 				if (RUV_COVERS_CSN == rc)
+ 				{
+ 					slapi_log_error(SLAPI_LOG_REPL,
+@@ -3626,7 +3626,7 @@ assign_csn_callback(const CSN *csn, void *data)
+ 	
+     if (NULL != r->min_csn_pl)
+     {
+-        if (csnplInsert(r->min_csn_pl, csn) != 0)
++        if (csnplInsert(r->min_csn_pl, csn, NULL) != 0)
+         {
+             char csn_str[CSN_STRSIZE]; /* For logging only */
+             /* Ack, we can't keep track of min csn. Punt. */
+@@ -3674,7 +3674,7 @@ abort_csn_callback(const CSN *csn, void *data)
+         }
+     }
+ 
+-    ruv_cancel_csn_inprogress (ruv, csn);
++    ruv_cancel_csn_inprogress (ruv, csn, replica_get_rid(r));
+     replica_unlock(r->repl_lock);
+ 
+     object_release (ruv_obj);
+diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
+index 5d6e1c3..c2d3bb4 100644
+--- a/ldap/servers/plugins/replication/repl5_ruv.c
++++ b/ldap/servers/plugins/replication/repl5_ruv.c
+@@ -77,6 +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);
+ 
+ /* API implementation */
+ 
+@@ -1602,6 +1603,7 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
+     char csn_str[CSN_STRSIZE];
+     int rc = RUV_SUCCESS;
+     int rid = csn_get_replicaid (csn);
++    CSN *prim_csn;
+ 
+     PR_ASSERT (ruv && csn);
+ 
+@@ -1639,8 +1641,12 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
+         rc = RUV_COVERS_CSN;
+         goto done;
+     }
+-
+-    rc = csnplInsert (replica->csnpl, csn);
++    prim_csn = get_thread_primary_csn();
++    if (prim_csn == NULL) {
++        set_thread_primary_csn(csn);
++        prim_csn = get_thread_primary_csn();
++    }
++    rc = csnplInsert (replica->csnpl, csn, prim_csn);
+     if (rc == 1)    /* we already seen this csn */
+     {
+         if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+@@ -1648,6 +1654,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);
+         rc = RUV_COVERS_CSN;    
+     }
+     else if(rc != 0)
+@@ -1672,24 +1679,36 @@ done:
+     return rc;
+ }
+ 
+-int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn)
++int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn, ReplicaId local_rid)
+ {
+     RUVElement* replica;
+     int rc = RUV_SUCCESS;
++    CSN *prim_csn = NULL;
++
+ 
+     PR_ASSERT (ruv && csn);
+ 
++    prim_csn = get_thread_primary_csn();
+     /* locate ruvElement */
+     slapi_rwlock_wrlock (ruv->lock);
+     replica = ruvGetReplica (ruv, csn_get_replicaid (csn));
+-    if (replica == NULL)
+-    {
++    if (replica == NULL) {
+         /* ONREPL - log error */
+-        rc = RUV_NOTFOUND;
+-        goto done;
+-    } 
+-
+-    rc = csnplRemove (replica->csnpl, csn);
++	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) {
++		replica = ruvGetReplica (ruv, local_rid);
++		rc = csnplRemoveAll (replica->csnpl, prim_csn);
++	}
++    } else {
++	rc = csnplRemove (replica->csnpl, csn);
++    }
+     if (rc != 0)
+         rc = RUV_NOTFOUND;
+     else
+@@ -1700,19 +1719,37 @@ done:
+     return rc;
+ }
+ 
+-int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, PRBool isLocal)
++int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, ReplicaId local_rid)
++{
++    int rc=RUV_SUCCESS;
++    RUVElement *replica;
++    ReplicaId prim_rid;
++
++    CSN *prim_csn = get_thread_primary_csn();
++
++    if (! csn_is_equal(csn, prim_csn)) {
++	/* not a primary csn, nothing to do */
++	return rc;
++    }
++    slapi_rwlock_wrlock (ruv->lock);
++    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_unlock (ruv->lock);
++    return rc;
++}
++static int
++ruv_update_ruv_element (RUV *ruv, RUVElement *replica, const CSN *csn, const char *replica_purl, PRBool isLocal)
+ {
+     int rc=RUV_SUCCESS;
+     char csn_str[CSN_STRSIZE];
+     CSN *max_csn;
+     CSN *first_csn = NULL;
+-    RUVElement *replica;
+     
+-    PR_ASSERT (ruv && csn);
+-
+-    slapi_rwlock_wrlock (ruv->lock);
+-
+-    replica = ruvGetReplica (ruv, csn_get_replicaid (csn));
+     if (replica == NULL)
+     {
+         /* we should have a ruv element at this point because it would have
+@@ -1722,7 +1759,7 @@ int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, PRBool i
+         goto done;
+     } 
+ 
+-	if (csnplCommit(replica->csnpl, csn) != 0)
++	if (csnplCommitAll(replica->csnpl, csn) != 0)
+ 	{
+ 		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "ruv_update_ruv: cannot commit csn %s\n",
+ 			            csn_as_string(csn, PR_FALSE, csn_str));
+@@ -1763,7 +1800,6 @@ int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, PRBool i
+ 	}
+ 
+ done:
+-    slapi_rwlock_unlock (ruv->lock);
+ 
+     return rc;
+ }
+diff --git a/ldap/servers/plugins/replication/repl5_ruv.h b/ldap/servers/plugins/replication/repl5_ruv.h
+index e9eff5a..c8960fd 100644
+--- a/ldap/servers/plugins/replication/repl5_ruv.h
++++ b/ldap/servers/plugins/replication/repl5_ruv.h
+@@ -109,8 +109,8 @@ 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);
+-int ruv_update_ruv (RUV *ruv, const CSN *csn, const char *replica_purl, PRBool isLocal);
++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_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/csn.c b/ldap/servers/slapd/csn.c
+index a3f4815..175f82a 100644
+--- a/ldap/servers/slapd/csn.c
++++ b/ldap/servers/slapd/csn.c
+@@ -268,6 +268,21 @@ csn_as_attr_option_string(CSNType t,const CSN *csn,char *ss)
+ 	return s;
+ }
+ 
++int
++csn_is_equal(const CSN *csn1, const CSN *csn2)
++{
++	int retval = 0;
++	if ((csn1 == NULL && csn2 == NULL) ||
++		(csn1 && csn2 &&
++		 csn1->tstamp == csn2->tstamp &&
++		 csn1->seqnum == csn2->seqnum &&
++		 csn1->rid == csn2->rid &&
++		 csn1->subseqnum == csn2->subseqnum)) {
++		retval = 1;
++	}
++	return retval;
++}
++
+ int 
+ csn_compare_ext(const CSN *csn1, const CSN *csn2, unsigned int flags)
+ {
+diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
+index 52d1c4a..e909e9c 100644
+--- a/ldap/servers/slapd/slapi-private.h
++++ b/ldap/servers/slapd/slapi-private.h
+@@ -166,6 +166,7 @@ time_t csn_get_time(const CSN *csn);
+ PRUint16 csn_get_seqnum(const CSN *csn);
+ PRUint16 csn_get_subseqnum(const CSN *csn);
+ char *csn_as_string(const CSN *csn, PRBool replicaIdOrder, char *ss); /* WARNING: ss must be CSN_STRSIZE bytes, or NULL. */
++int csn_is_equal(const CSN *csn1, const CSN *csn2);
+ int csn_compare(const CSN *csn1, const CSN *csn2);
+ int csn_compare_ext(const CSN *csn1, const CSN *csn2, unsigned int flags);
+ #define CSN_COMPARE_SKIP_SUBSEQ 0x1
+@@ -181,6 +182,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);
+ /*
+  * csnset.c
+  */
+-- 
+2.9.3
+
diff --git a/SOURCES/0065-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch b/SOURCES/0065-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
new file mode 100644
index 0000000..b0782d4
--- /dev/null
+++ b/SOURCES/0065-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
@@ -0,0 +1,36 @@
+From 0085cfb4c4ff6722898e97704a67dcdfcba53388 Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@redhat.com>
+Date: Wed, 25 Jan 2017 13:39:08 -0800
+Subject: [PATCH 65/67] Ticket 49008 backport 1.3.5 : aborted operation can
+ leave RUV in incorrect state
+
+Description: Fixed 2 backport errors in commit 79a3deafe943a3ce5c31c50272939146d17bd7ac.
+(cherry picked from commit 3fa6596bdc677cdb3fb65b7baf6fd567485c91a7)
+---
+ ldap/servers/plugins/replication/csnpl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/csnpl.c b/ldap/servers/plugins/replication/csnpl.c
+index db1ae13..a696fc1 100644
+--- a/ldap/servers/plugins/replication/csnpl.c
++++ b/ldap/servers/plugins/replication/csnpl.c
+@@ -220,14 +220,14 @@ int csnplCommitAll (CSNPL *csnpl, const CSN *csn)
+ 	char csn_str[CSN_STRSIZE];
+ 
+ 	csn_as_string(csn, PR_FALSE, csn_str);
+-	slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
++	slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, 
+ 		            "csnplCommitALL: committing all csns for csn %s\n", csn_str);
+ 	slapi_rwlock_wrlock (csnpl->csnLock);
+ 	data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
+ 	while (NULL != data)
+ 	{
+ 		csn_as_string(data->csn, PR_FALSE, csn_str);
+-		slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
++		slapi_log_error(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)) {
+-- 
+2.9.3
+
diff --git a/SOURCES/0066-Ticket-49079-deadlock-on-cos-cache-rebuild.patch b/SOURCES/0066-Ticket-49079-deadlock-on-cos-cache-rebuild.patch
new file mode 100644
index 0000000..af757e4
--- /dev/null
+++ b/SOURCES/0066-Ticket-49079-deadlock-on-cos-cache-rebuild.patch
@@ -0,0 +1,207 @@
+From 5391c666e58af5841eab88c98505f99c8ed20d6b Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Tue, 10 Jan 2017 14:32:53 +0100
+Subject: [PATCH 66/67] Ticket 49079: deadlock on cos cache rebuild
+
+Bug Description:
+    To rebuild the cache cos_cache_creation the thread gets cos definitions from backend.
+    It means change_lock is held then cos_cache_creation will acquire some backend pages.
+
+    A deadlock can happen if cos_post_op is called while backend is locked.
+    For example if a bepreop (urp) does an internal update on a cos definition.
+    Then the thread holds backend pages, that will be needed by cos_cache_creation,
+    and will acquire change_lock for notification of the cos_cache thread
+
+Fix Description:
+
+    Let cos cache rebuild thread run without holding change_lock.
+    The lock prevents parallel run but a flag can do the same.
+
+https://fedorahosted.org/389/ticket/49079
+
+Reviewed by: William Brown and Ludwig Krispenz (thanks to you both !!)
+
+Platforms tested: F23
+
+Flag Day: no
+
+Doc impact: no
+
+(cherry picked from commit ac44337bd97fe63071e7d83e9dcd788f2af1feab)
+(cherry picked from commit 3ac12cb94a8873b0fa4ddb12f924cc58bd9c9872)
+---
+ ldap/servers/plugins/cos/cos_cache.c | 73 ++++++++++++++++++++++++++++++------
+ 1 file changed, 61 insertions(+), 12 deletions(-)
+
+diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
+index 8a32630..87b4ba5 100644
+--- a/ldap/servers/plugins/cos/cos_cache.c
++++ b/ldap/servers/plugins/cos/cos_cache.c
+@@ -111,7 +111,9 @@ void * cos_get_plugin_identity();
+ /* 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;
+ 
+ /* service definition cache structs */
+ 
+@@ -199,7 +201,8 @@ typedef struct _cos_cache cosCache;
+ static cosCache *pCache; /* always the current global cache, only use getref to get */
+ 
+ /* the place to start if you want a new cache */
+-static int cos_cache_create();
++static int cos_cache_create_unlock(void);
++static int cos_cache_creation_lock(void);
+ 
+ /* cache index related functions */
+ static int cos_cache_index_all(cosCache *pCache);
+@@ -386,7 +389,7 @@ static void cos_cache_wait_on_change(void *arg)
+ 	pCache = 0;
+ 
+ 	/* create initial cache */
+-	cos_cache_create();
++	cos_cache_creation_lock();
+ 
+         slapi_lock_mutex(start_lock);
+         started = 1;
+@@ -419,7 +422,7 @@ static void cos_cache_wait_on_change(void *arg)
+ 		 * before we go running off doing lots of stuff lets check if we should stop
+ 		*/
+ 		if(keeprunning) {
+-			cos_cache_create();				
++			cos_cache_creation_lock();
+ 		}
+ 		cos_cache_notify_flag = 0; /* Dealt with it */
+ 	}/* while */
+@@ -431,22 +434,25 @@ static void cos_cache_wait_on_change(void *arg)
+ 	LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_wait_on_change thread exit\n",0,0,0);
+ }
+ 
++
+ /*
+-	cos_cache_create
++	cos_cache_create_unlock
+ 	---------------------
+ 	Walks the definitions in the DIT and creates the cache.
+ 	Once created, it swaps the new cache for the old one,
+ 	releasing its refcount to the old cache and allowing it
+ 	to be destroyed.
++
++        called while change_lock is NOT held
+ */
+-static int cos_cache_create()
++static int cos_cache_create_unlock(void)
+ {
+ 	int ret = -1;
+ 	cosCache *pNewCache;
+ 	static int firstTime = 1;
+ 	int cache_built = 0;
+ 
+-	LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_cache_create\n",0,0,0);
++	LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_cache_create_unlock\n",0,0,0);
+ 
+ 	pNewCache = (cosCache*)slapi_ch_malloc(sizeof(cosCache));
+ 	if(pNewCache)
+@@ -509,21 +515,21 @@ static int cos_cache_create()
+ 				{
+ 					/* we should not go on without proper schema checking */
+ 					cos_cache_release(pNewCache);
+-					LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create: failed to cache the schema\n",0,0,0);			
++					LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create_unlock: failed to cache the schema\n",0,0,0);			
+ 				}
+ 			}
+ 			else
+ 			{
+ 				/* currently we cannot go on without the indexes */
+ 				cos_cache_release(pNewCache);
+-				LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create: failed to index cache\n",0,0,0);			
++				LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create_unlock: failed to index cache\n",0,0,0);			
+ 			}
+ 		}
+ 		else
+ 		{
+ 			if(firstTime)
+ 			{
+-				LDAPDebug( LDAP_DEBUG_PLUGIN, "cos_cache_create: cos disabled\n",0,0,0);
++				LDAPDebug( LDAP_DEBUG_PLUGIN, "cos_cache_create_unlock: cos disabled\n",0,0,0);
+ 				firstTime = 0;
+ 			}
+ 
+@@ -531,7 +537,7 @@ static int cos_cache_create()
+ 		}
+ 	}
+ 	else
+-		LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create: memory allocation failure\n",0,0,0);
++		LDAPDebug( LDAP_DEBUG_ANY, "cos_cache_create_unlock: memory allocation failure\n",0,0,0);
+ 
+ 
+ 	/* make sure we have a new cache */
+@@ -563,10 +569,53 @@ static int cos_cache_create()
+ 		
+ 	}
+ 
+-	LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_create\n",0,0,0);
++	LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_create_unlock\n",0,0,0);
+ 	return ret;
+ }
+ 
++/* cos_cache_creation_lock is called with change_lock being hold:
++ *    slapi_lock_mutex(change_lock)
++ *
++ * To rebuild the cache cos_cache_creation gets cos definitions from backend, that
++ * means change_lock is held then cos_cache_creation will acquire some backend pages.
++ *
++ * A deadlock can happen if cos_post_op is called while backend is locked. 
++ * For example if a bepreop (urp) does an internal update on a cos definition,
++ * the thread holds backend pages that will be needed by cos_cache_creation.
++ *
++ * A solution is to use a flag 'cos_cache_at_work' protected by change_lock,
++ * release change_lock, recreate the cos_cache, acquire change_lock reset the flag.
++ *
++ * returned value: result of cos_cache_create_unlock
++ *
++ */
++static int cos_cache_creation_lock(void)
++{
++	int ret = -1;
++	int max_tries = 10;
++
++	for (; max_tries != 0; max_tries--) {
++		/* if the cos_cache is already under work (cos_cache_create_unlock)
++		 * wait 1 second
++		 */
++		if (cos_cache_at_work) {
++			slapi_log_error(SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_creation_lock already rebuilding cos_cache... retry\n");
++			DS_Sleep (PR_MillisecondsToInterval(1000));
++			continue;
++		}
++		cos_cache_at_work = PR_TRUE;
++		slapi_unlock_mutex(change_lock);
++		ret = cos_cache_create_unlock();
++		slapi_lock_mutex(change_lock);
++		cos_cache_at_work = PR_FALSE;
++		break;
++	}
++	if (!max_tries) {
++		slapi_log_error(SLAPI_LOG_FATAL, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_creation_lock  rebuilt was to long, skip this rebuild\n");
++	}
++
++	return ret;
++}
+ 
+ /*
+ 	cos_cache_build_definition_list
+@@ -1639,7 +1688,7 @@ int cos_cache_getref(cos_cache **pptheCache)
+ 		slapi_lock_mutex(change_lock);
+ 		if(pCache == NULL)
+ 		{
+-			if(cos_cache_create())
++			if(cos_cache_creation_lock())
+ 			{
+ 				/* there was a problem or no COS definitions were found */
+ 				LDAPDebug( LDAP_DEBUG_PLUGIN, "cos_cache_getref: no cos cache created\n",0,0,0);
+-- 
+2.9.3
+
diff --git a/SOURCES/0067-Ticket-49016-un-register-migration-remove-may-fail-i.patch b/SOURCES/0067-Ticket-49016-un-register-migration-remove-may-fail-i.patch
new file mode 100644
index 0000000..b2fa67d
--- /dev/null
+++ b/SOURCES/0067-Ticket-49016-un-register-migration-remove-may-fail-i.patch
@@ -0,0 +1,50 @@
+From 451838933f9989d1ff9c46dbb3cae7619166a4d8 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Fri, 21 Oct 2016 16:28:59 +0200
+Subject: [PATCH 67/67] Ticket 49016 - (un)register/migration/remove may fail
+ if there is no suffix on 'userRoot' backend
+
+Bug Description:
+    If an instance has no suffix on 'userRoot' backend, then the info structure
+    may contain empty 'Suffix'.
+    In fact if the last backend has no suffix (like cn=config), it overwite all
+    previsously found value.
+    This affect register (and possibly unregister/migrate/remove)
+
+Fix Description:
+    Before overwriting the 'Suffix' value, check that the found backend contains
+    'nsslapd-suffix'.
+
+https://fedorahosted.org/389/ticket/49016
+
+Reviewed by: Noriko Hosoi (Thank you Noriko)
+
+Platforms tested: RHEL 7.2
+
+Flag Day: no
+
+Doc impact: no
+
+(cherry picked from commit 1bafab5ae1e894ae3680679e03e457b9ace7e7d2)
+---
+ ldap/admin/src/scripts/DSUtil.pm.in | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ldap/admin/src/scripts/DSUtil.pm.in b/ldap/admin/src/scripts/DSUtil.pm.in
+index 756d6ea..eac59a3 100644
+--- a/ldap/admin/src/scripts/DSUtil.pm.in
++++ b/ldap/admin/src/scripts/DSUtil.pm.in
+@@ -975,7 +975,9 @@ sub createInfFromConfig {
+     }
+     # use the userRoot suffix if available
+     while ($ent) {
+-        $suffix = $ent->getValues('nsslapd-suffix');
++        if ($ent->getValues('nsslapd-suffix')) {
++            $suffix = $ent->getValues('nsslapd-suffix');
++        }
+         last if ($ent->hasValue('cn', 'userRoot', 1));
+         $ent = $conn->nextEntry();
+     }
+-- 
+2.9.3
+
diff --git a/SOURCES/0068-Ticket-49016-un-register-migration-remove-may-fail-i.patch b/SOURCES/0068-Ticket-49016-un-register-migration-remove-may-fail-i.patch
new file mode 100644
index 0000000..ba32e9c
--- /dev/null
+++ b/SOURCES/0068-Ticket-49016-un-register-migration-remove-may-fail-i.patch
@@ -0,0 +1,59 @@
+From 99a0def5c6b9910616d95ee7cd15ecad5b406951 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Mon, 30 Jan 2017 17:38:01 +0100
+Subject: [PATCH] Ticket 49016 - (un)register/migration/remove may fail if
+ there is no suffix on 'userRoot' backend
+
+Bug Description:
+    Previous fix was incomplete in case none of the backend entries have
+    'nsslapd-suffix' value
+
+Fix Description:
+
+    Just return if $suffix keep unmodified
+
+https://fedorahosted.org/389/ticket/49016
+
+Reviewed by: nhosoi
+
+Platforms tested: F23, F25
+
+Flag Day: no
+
+Doc impact: no
+
+(cherry picked from commit bd5fdfc8f4a560eae99672b712235c1260ee42b0)
+(cherry picked from commit 1abb0ffb2930d019f58d5dac1937ddbb56c9287f)
+---
+ ldap/admin/src/scripts/DSUtil.pm.in | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/ldap/admin/src/scripts/DSUtil.pm.in b/ldap/admin/src/scripts/DSUtil.pm.in
+index eac59a3..c8eb14d 100644
+--- a/ldap/admin/src/scripts/DSUtil.pm.in
++++ b/ldap/admin/src/scripts/DSUtil.pm.in
+@@ -965,7 +965,7 @@ sub createInfFromConfig {
+     $inf->{slapd}->{ServerPort} = $ent->getValues('nsslapd-port');
+     $inf->{slapd}->{ServerIdentifier} = $id;
+ 
+-    my $suffix;
++    my $suffix = "";
+     $ent = $conn->search("cn=ldbm database,cn=plugins,cn=config",
+                          "one", "(objectclass=*)");
+     if (!$ent) {
+@@ -981,6 +981,12 @@ sub createInfFromConfig {
+         last if ($ent->hasValue('cn', 'userRoot', 1));
+         $ent = $conn->nextEntry();
+     }
++    if ( "" eq "$suffix" )
++    {
++        push @{$errs}, "error_opening_dseldif", $fname, $!;
++        $conn->close();
++        return 0;
++    }
+ 
+     # we also need the instance dir
+     $ent = $conn->search("cn=config", "base", "(objectclass=*)");
+-- 
+2.9.3
+
diff --git a/SOURCES/0069-fix-for-reg-in-49008-check-if-ruv-element-exists.patch b/SOURCES/0069-fix-for-reg-in-49008-check-if-ruv-element-exists.patch
new file mode 100644
index 0000000..e85d043
--- /dev/null
+++ b/SOURCES/0069-fix-for-reg-in-49008-check-if-ruv-element-exists.patch
@@ -0,0 +1,34 @@
+From 7a5d77d8a65d65ed7c5fa94abf952669993f45c2 Mon Sep 17 00:00:00 2001
+From: Ludwig Krispenz <lkrispen@redhat.com>
+Date: Tue, 7 Feb 2017 17:02:00 +0100
+Subject: [PATCH] fix for reg in 49008, check if ruv element exists
+
+(cherry picked from commit 23d98baa8aadab80691680ba065563ad1e35591c)
+---
+ ldap/servers/plugins/replication/repl5_ruv.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
+index c2d3bb4..5086313 100644
+--- a/ldap/servers/plugins/replication/repl5_ruv.c
++++ b/ldap/servers/plugins/replication/repl5_ruv.c
+@@ -1703,8 +1703,14 @@ int ruv_cancel_csn_inprogress (RUV *ruv, const CSN *csn, ReplicaId local_rid)
+ 	replica = ruvGetReplica (ruv, prim_rid);
+ 	rc = csnplRemoveAll (replica->csnpl, prim_csn);
+ 	if (prim_rid != local_rid) {
+-		replica = ruvGetReplica (ruv, local_rid);
+-		rc = csnplRemoveAll (replica->csnpl, prim_csn);
++		if( local_rid != READ_ONLY_REPLICA_ID) {
++			replica = ruvGetReplica (ruv, local_rid);
++			if (replica) {
++				rc = csnplRemoveAll (replica->csnpl, prim_csn);
++			} else {
++				rc = RUV_NOTFOUND;
++			}
++		}
+ 	}
+     } else {
+ 	rc = csnplRemove (replica->csnpl, csn);
+-- 
+2.7.4
+
diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec
index 02002a0..cdda586 100644
--- a/SPECS/389-ds-base.spec
+++ b/SPECS/389-ds-base.spec
@@ -34,9 +34,9 @@
 Summary:          389 Directory Server (base)
 Name:             389-ds-base
 Version:          1.3.5.10
-Release:          %{?relprefix}15%{?prerel}%{?dist}
+Release:          %{?relprefix}18%{?prerel}%{?dist}
 License:          GPLv3+
-URL:              https://port389.org/
+URL:              https://www.port389.org/
 Group:            System Environment/Daemons
 BuildRoot:        %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Obsoletes:        %{name}-selinux
@@ -196,6 +196,15 @@ Patch57:          0057-Ticket-49020-do-not-treat-missing-csn-as-fatal.patch
 Patch58:          0058-Ticket-48964-cleanallruv-changelog-purging-removes-w.patch
 Patch59:          0059-Ticket-48964-should-not-free-repl-name-after-purging.patch
 Patch60:          0060-Ticket-49074-incompatible-nsEncryptionConfig-object-.patch
+Patch61:          0061-Ticket-49080-shadowExpire-should-not-be-a-calculated.patch
+Patch62:          0062-Ticket-49082-Fix-password-expiration-related-shadow-.patch
+Patch63:          0063-Ticket-49082-Adjusted-the-CI-test-case-to-the-fix.patch
+Patch64:          0064-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
+Patch65:          0065-Ticket-49008-backport-1.3.5-aborted-operation-can-le.patch
+Patch66:          0066-Ticket-49079-deadlock-on-cos-cache-rebuild.patch
+Patch67:          0067-Ticket-49016-un-register-migration-remove-may-fail-i.patch
+Patch68:          0068-Ticket-49016-un-register-migration-remove-may-fail-i.patch
+Patch69:          0069-fix-for-reg-in-49008-check-if-ruv-element-exists.patch
 
 %description
 389 Directory Server is an LDAPv3 compliant server.  The base package includes
@@ -342,6 +351,15 @@ cp %{SOURCE2} README.devel
 %patch58 -p1
 %patch59 -p1
 %patch60 -p1
+%patch61 -p1
+%patch62 -p1
+%patch63 -p1
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
+%patch67 -p1
+%patch68 -p1
+%patch69 -p1
 
 %build
 %if %{use_nunc_stans}
@@ -579,6 +597,21 @@ fi
 %{_sysconfdir}/%{pkgname}/dirsrvtests
 
 %changelog
+* Thu Feb 16 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.5.10-18
+- Release 1.3.5.10-18
+- Resolves: bug 1387340 - Aborted operation can leave RUV in incorrect state 
+
+* Tue Jan 31 2017 Noriko Hosoi <nhosoi@redhat.com> - 1.3.5.10-17
+- Release 1.3.5.10-17
+- Resolves: bug 1414677 - (un)register/migration/remove may fail if there is no suffix (DS 49016)
+
+* Wed Jan 25 2017 Noriko Hosoi <nhosoi@redhat.com> - 1.3.5.10-16
+- Release 1.3.5.10-16
+- Resolves: bug 1414677 - (un)register/migration/remove may fail if there is no suffix (DS 49016)
+- Resolves: bug 1414678 - deadlock on cos cache rebuild (DS 49079)
+- Resolves: bug 1414679 - Release 1.3.5 may allow expired accounts access to systems (DS 49080, DS 49082)
+- Resolves: bug 1416368 - Aborted operation can leave RUV in incorrect state (DS 49008)
+
 * Wed Jan  4 2017 Noriko Hosoi <nhosoi@redhat.com> - 1.3.5.10-15
 - Release 1.3.5.10-15
 - Resolves: bug 1402325 - do not treat missing csn as fatal (DS 48964)