From a1ba67894ae778cf557f13fe5d7fa81d57a2aca7 Mon Sep 17 00:00:00 2001
From: Ludwig Krispenz <lkrispen@redhat.com>
Date: Tue, 13 Aug 2013 14:30:16 +0200
Subject: [PATCH] Initial implementation of rfc4533 as plugin

---
 Makefile.am                               |  26 +-
 Makefile.in                               | 169 ++++---
 ldap/admin/src/scripts/50contentsync.ldif |  13 +
 ldap/ldif/template-dse.ldif.in            |  12 +
 ldap/servers/plugins/sync/sync.h          | 168 +++++++
 ldap/servers/plugins/sync/sync_init.c     | 161 +++++++
 ldap/servers/plugins/sync/sync_persist.c  | 701 ++++++++++++++++++++++++++++++
 ldap/servers/plugins/sync/sync_refresh.c  | 318 ++++++++++++++
 ldap/servers/plugins/sync/sync_util.c     | 423 ++++++++++++++++++
 ldap/servers/slapd/connection.c           |   7 +-
 ldap/servers/slapd/plugin.c               |   9 +
 ldap/servers/slapd/proto-slap.h           |   2 +
 ldap/servers/slapd/result.c               |  67 ++-
 ldap/servers/slapd/slapi-plugin.h         |   2 +
 14 files changed, 2003 insertions(+), 75 deletions(-)
 create mode 100644 ldap/admin/src/scripts/50contentsync.ldif
 create mode 100644 ldap/servers/plugins/sync/sync.h
 create mode 100644 ldap/servers/plugins/sync/sync_init.c
 create mode 100644 ldap/servers/plugins/sync/sync_persist.c
 create mode 100644 ldap/servers/plugins/sync/sync_refresh.c
 create mode 100644 ldap/servers/plugins/sync/sync_util.c

diff --git a/Makefile.am b/Makefile.am
index 37647b3..ba3d76a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -225,11 +225,11 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
 	libdes-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
 	liblinkedattrs-plugin.la libmanagedentries-plugin.la \
 	libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
+	libcontentsync-plugin.la \
 	libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
 	libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
 	libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \
-	libacctusability-plugin.la librootdn-access-plugin.la \
-	libwhoami-plugin.la $(LIBACCTPOLICY_PLUGIN) \
+	libacctusability-plugin.la librootdn-access-plugin.la $(LIBACCTPOLICY_PLUGIN) \
 	$(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \
 	$(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) $(LIBPOSIX_WINSYNC_PLUGIN)
 
@@ -564,6 +564,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50refintprecedence.ldif \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/50rootdnaccesscontrolplugin.ldif \
+	ldap/admin/src/scripts/50contentsync.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/70upgradefromldif.pl \
 	ldap/admin/src/scripts/80upgradednformat.pl \
@@ -1135,6 +1136,18 @@ libpwdstorage_plugin_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK) $(LIBCRYPT
 libpwdstorage_plugin_la_LDFLAGS = -avoid-version
 
 #------------------------
+# libcontentsync-plugin
+#------------------------
+libcontentsync_plugin_la_SOURCES = ldap/servers/plugins/sync/sync_init.c \
+	ldap/servers/plugins/sync/sync_util.c \
+	ldap/servers/plugins/sync/sync_refresh.c \
+	ldap/servers/plugins/sync/sync_persist.c
+
+libcontentsync_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+libcontentsync_plugin_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK) $(LIBCRYPT)
+libcontentsync_plugin_la_LDFLAGS = -avoid-version
+
+#------------------------
 # libreferint-plugin
 #------------------------
 libreferint_plugin_la_SOURCES = ldap/servers/plugins/referint/referint.c
@@ -1298,16 +1311,7 @@ libviews_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
 libviews_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
 libviews_plugin_la_LDFLAGS = -avoid-version
 
-#------------------------
-# libwhoami-plugin
-#------------------------
-libwhoami_plugin_la_SOURCES = ldap/servers/plugins/whoami/whoami.c
 
-libwhoami_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
-libwhoami_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
-libwhoami_plugin_la_LDFLAGS = -avoid-version
-
-#------------------------
 #////////////////////////////////////////////////////////////////
 #
 #   Programs
diff --git a/Makefile.in b/Makefile.in
index e8bea15..a23588b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -322,6 +322,18 @@ am_libcollation_plugin_la_OBJECTS = ldap/servers/plugins/collation/libcollation_
 	ldap/servers/plugins/collation/libcollation_plugin_la-config.lo \
 	ldap/servers/plugins/collation/libcollation_plugin_la-orfilter.lo
 libcollation_plugin_la_OBJECTS = $(am_libcollation_plugin_la_OBJECTS)
+libcontentsync_plugin_la_DEPENDENCIES = libslapd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am_libcontentsync_plugin_la_OBJECTS = ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo \
+	ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo \
+	ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo \
+	ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo
+libcontentsync_plugin_la_OBJECTS =  \
+	$(am_libcontentsync_plugin_la_OBJECTS)
+libcontentsync_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libcontentsync_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
 libcos_plugin_la_DEPENDENCIES = libslapd.la $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
 am_libcos_plugin_la_OBJECTS =  \
@@ -847,14 +859,6 @@ libviews_plugin_la_OBJECTS = $(am_libviews_plugin_la_OBJECTS)
 libviews_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(libviews_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
-libwhoami_plugin_la_DEPENDENCIES = libslapd.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
-am_libwhoami_plugin_la_OBJECTS =  \
-	ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo
-libwhoami_plugin_la_OBJECTS = $(am_libwhoami_plugin_la_OBJECTS)
-libwhoami_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(libwhoami_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS)
 am_dbscan_bin_OBJECTS =  \
 	ldap/servers/slapd/tools/dbscan_bin-dbscan.$(OBJEXT)
@@ -1040,9 +1044,11 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
 	$(libautomember_plugin_la_SOURCES) $(libback_ldbm_la_SOURCES) \
 	$(libbitwise_plugin_la_SOURCES) \
 	$(libchainingdb_plugin_la_SOURCES) \
-	$(libcollation_plugin_la_SOURCES) $(libcos_plugin_la_SOURCES) \
-	$(libderef_plugin_la_SOURCES) $(libdes_plugin_la_SOURCES) \
-	$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
+	$(libcollation_plugin_la_SOURCES) \
+	$(libcontentsync_plugin_la_SOURCES) \
+	$(libcos_plugin_la_SOURCES) $(libderef_plugin_la_SOURCES) \
+	$(libdes_plugin_la_SOURCES) $(libdistrib_plugin_la_SOURCES) \
+	$(libdna_plugin_la_SOURCES) \
 	$(libhttp_client_plugin_la_SOURCES) \
 	$(liblinkedattrs_plugin_la_SOURCES) \
 	$(libmanagedentries_plugin_la_SOURCES) \
@@ -1059,10 +1065,10 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
 	$(libschemareload_plugin_la_SOURCES) $(libslapd_la_SOURCES) \
 	$(libstatechange_plugin_la_SOURCES) \
 	$(libsyntax_plugin_la_SOURCES) $(libusn_plugin_la_SOURCES) \
-	$(libviews_plugin_la_SOURCES) $(libwhoami_plugin_la_SOURCES) \
-	$(dbscan_bin_SOURCES) $(dsktune_bin_SOURCES) \
-	$(infadd_bin_SOURCES) $(ldap_agent_bin_SOURCES) \
-	$(ldclt_bin_SOURCES) $(ldif_bin_SOURCES) $(makstrdb_SOURCES) \
+	$(libviews_plugin_la_SOURCES) $(dbscan_bin_SOURCES) \
+	$(dsktune_bin_SOURCES) $(infadd_bin_SOURCES) \
+	$(ldap_agent_bin_SOURCES) $(ldclt_bin_SOURCES) \
+	$(ldif_bin_SOURCES) $(makstrdb_SOURCES) \
 	$(migratecred_bin_SOURCES) $(mmldif_bin_SOURCES) \
 	$(ns_slapd_SOURCES) $(pwdhash_bin_SOURCES) \
 	$(rsearch_bin_SOURCES)
@@ -1074,9 +1080,11 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
 	$(libautomember_plugin_la_SOURCES) $(libback_ldbm_la_SOURCES) \
 	$(libbitwise_plugin_la_SOURCES) \
 	$(libchainingdb_plugin_la_SOURCES) \
-	$(libcollation_plugin_la_SOURCES) $(libcos_plugin_la_SOURCES) \
-	$(libderef_plugin_la_SOURCES) $(libdes_plugin_la_SOURCES) \
-	$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
+	$(libcollation_plugin_la_SOURCES) \
+	$(libcontentsync_plugin_la_SOURCES) \
+	$(libcos_plugin_la_SOURCES) $(libderef_plugin_la_SOURCES) \
+	$(libdes_plugin_la_SOURCES) $(libdistrib_plugin_la_SOURCES) \
+	$(libdna_plugin_la_SOURCES) \
 	$(libhttp_client_plugin_la_SOURCES) \
 	$(liblinkedattrs_plugin_la_SOURCES) \
 	$(libmanagedentries_plugin_la_SOURCES) \
@@ -1094,13 +1102,13 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
 	$(am__libslapd_la_SOURCES_DIST) \
 	$(libstatechange_plugin_la_SOURCES) \
 	$(libsyntax_plugin_la_SOURCES) $(libusn_plugin_la_SOURCES) \
-	$(libviews_plugin_la_SOURCES) $(libwhoami_plugin_la_SOURCES) \
-	$(dbscan_bin_SOURCES) $(dsktune_bin_SOURCES) \
-	$(infadd_bin_SOURCES) $(ldap_agent_bin_SOURCES) \
-	$(am__ldclt_bin_SOURCES_DIST) $(ldif_bin_SOURCES) \
-	$(makstrdb_SOURCES) $(migratecred_bin_SOURCES) \
-	$(mmldif_bin_SOURCES) $(am__ns_slapd_SOURCES_DIST) \
-	$(pwdhash_bin_SOURCES) $(rsearch_bin_SOURCES)
+	$(libviews_plugin_la_SOURCES) $(dbscan_bin_SOURCES) \
+	$(dsktune_bin_SOURCES) $(infadd_bin_SOURCES) \
+	$(ldap_agent_bin_SOURCES) $(am__ldclt_bin_SOURCES_DIST) \
+	$(ldif_bin_SOURCES) $(makstrdb_SOURCES) \
+	$(migratecred_bin_SOURCES) $(mmldif_bin_SOURCES) \
+	$(am__ns_slapd_SOURCES_DIST) $(pwdhash_bin_SOURCES) \
+	$(rsearch_bin_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -1502,11 +1510,11 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
 	libdes-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
 	liblinkedattrs-plugin.la libmanagedentries-plugin.la \
 	libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
+	libcontentsync-plugin.la \
 	libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
 	libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
 	libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \
-	libacctusability-plugin.la librootdn-access-plugin.la \
-	libwhoami-plugin.la $(LIBACCTPOLICY_PLUGIN) \
+	libacctusability-plugin.la librootdn-access-plugin.la $(LIBACCTPOLICY_PLUGIN) \
 	$(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \
 	$(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) $(LIBPOSIX_WINSYNC_PLUGIN)
 
@@ -1837,6 +1845,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
 	ldap/admin/src/scripts/50refintprecedence.ldif \
 	ldap/admin/src/scripts/50retroclprecedence.ldif \
 	ldap/admin/src/scripts/50rootdnaccesscontrolplugin.ldif \
+	ldap/admin/src/scripts/50contentsync.ldif \
 	ldap/admin/src/scripts/60upgradeschemafiles.pl \
 	ldap/admin/src/scripts/70upgradefromldif.pl \
 	ldap/admin/src/scripts/80upgradednformat.pl \
@@ -2344,6 +2353,18 @@ libpwdstorage_plugin_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK) $(LIBCRYPT
 libpwdstorage_plugin_la_LDFLAGS = -avoid-version
 
 #------------------------
+# libcontentsync-plugin
+#------------------------
+libcontentsync_plugin_la_SOURCES = ldap/servers/plugins/sync/sync_init.c \
+	ldap/servers/plugins/sync/sync_util.c \
+	ldap/servers/plugins/sync/sync_refresh.c \
+	ldap/servers/plugins/sync/sync_persist.c
+
+libcontentsync_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+libcontentsync_plugin_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK) $(LIBCRYPT)
+libcontentsync_plugin_la_LDFLAGS = -avoid-version
+
+#------------------------
 # libreferint-plugin
 #------------------------
 libreferint_plugin_la_SOURCES = ldap/servers/plugins/referint/referint.c
@@ -2503,15 +2524,6 @@ libviews_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
 libviews_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
 libviews_plugin_la_LDFLAGS = -avoid-version
 
-#------------------------
-# libwhoami-plugin
-#------------------------
-libwhoami_plugin_la_SOURCES = ldap/servers/plugins/whoami/whoami.c
-libwhoami_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
-libwhoami_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
-libwhoami_plugin_la_LDFLAGS = -avoid-version
-
-#------------------------
 #////////////////////////////////////////////////////////////////
 #
 #   Programs
@@ -3372,6 +3384,26 @@ ldap/servers/plugins/collation/libcollation_plugin_la-orfilter.lo:  \
 	ldap/servers/plugins/collation/$(DEPDIR)/$(am__dirstamp)
 libcollation-plugin.la: $(libcollation_plugin_la_OBJECTS) $(libcollation_plugin_la_DEPENDENCIES) $(EXTRA_libcollation_plugin_la_DEPENDENCIES) 
 	$(libcollation_plugin_la_LINK) -rpath $(serverplugindir) $(libcollation_plugin_la_OBJECTS) $(libcollation_plugin_la_LIBADD) $(LIBS)
+ldap/servers/plugins/sync/$(am__dirstamp):
+	@$(MKDIR_P) ldap/servers/plugins/sync
+	@: > ldap/servers/plugins/sync/$(am__dirstamp)
+ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) ldap/servers/plugins/sync/$(DEPDIR)
+	@: > ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo:  \
+	ldap/servers/plugins/sync/$(am__dirstamp) \
+	ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo:  \
+	ldap/servers/plugins/sync/$(am__dirstamp) \
+	ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo:  \
+	ldap/servers/plugins/sync/$(am__dirstamp) \
+	ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo:  \
+	ldap/servers/plugins/sync/$(am__dirstamp) \
+	ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+libcontentsync-plugin.la: $(libcontentsync_plugin_la_OBJECTS) $(libcontentsync_plugin_la_DEPENDENCIES) $(EXTRA_libcontentsync_plugin_la_DEPENDENCIES) 
+	$(libcontentsync_plugin_la_LINK) -rpath $(serverplugindir) $(libcontentsync_plugin_la_OBJECTS) $(libcontentsync_plugin_la_LIBADD) $(LIBS)
 ldap/servers/plugins/cos/$(am__dirstamp):
 	@$(MKDIR_P) ldap/servers/plugins/cos
 	@: > ldap/servers/plugins/cos/$(am__dirstamp)
@@ -4415,17 +4447,6 @@ ldap/servers/plugins/views/libviews_plugin_la-views.lo:  \
 	ldap/servers/plugins/views/$(DEPDIR)/$(am__dirstamp)
 libviews-plugin.la: $(libviews_plugin_la_OBJECTS) $(libviews_plugin_la_DEPENDENCIES) $(EXTRA_libviews_plugin_la_DEPENDENCIES) 
 	$(libviews_plugin_la_LINK) -rpath $(serverplugindir) $(libviews_plugin_la_OBJECTS) $(libviews_plugin_la_LIBADD) $(LIBS)
-ldap/servers/plugins/whoami/$(am__dirstamp):
-	@$(MKDIR_P) ldap/servers/plugins/whoami
-	@: > ldap/servers/plugins/whoami/$(am__dirstamp)
-ldap/servers/plugins/whoami/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) ldap/servers/plugins/whoami/$(DEPDIR)
-	@: > ldap/servers/plugins/whoami/$(DEPDIR)/$(am__dirstamp)
-ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo:  \
-	ldap/servers/plugins/whoami/$(am__dirstamp) \
-	ldap/servers/plugins/whoami/$(DEPDIR)/$(am__dirstamp)
-libwhoami-plugin.la: $(libwhoami_plugin_la_OBJECTS) $(libwhoami_plugin_la_DEPENDENCIES) $(EXTRA_libwhoami_plugin_la_DEPENDENCIES) 
-	$(libwhoami_plugin_la_LINK) -rpath $(serverplugindir) $(libwhoami_plugin_la_OBJECTS) $(libwhoami_plugin_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
 	@$(NORMAL_INSTALL)
 	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -5016,6 +5037,8 @@ mostlyclean-compile:
 	-rm -f ldap/servers/plugins/schema_reload/*.lo
 	-rm -f ldap/servers/plugins/statechange/*.$(OBJEXT)
 	-rm -f ldap/servers/plugins/statechange/*.lo
+	-rm -f ldap/servers/plugins/sync/*.$(OBJEXT)
+	-rm -f ldap/servers/plugins/sync/*.lo
 	-rm -f ldap/servers/plugins/syntaxes/*.$(OBJEXT)
 	-rm -f ldap/servers/plugins/syntaxes/*.lo
 	-rm -f ldap/servers/plugins/uiduniq/*.$(OBJEXT)
@@ -5024,8 +5047,6 @@ mostlyclean-compile:
 	-rm -f ldap/servers/plugins/usn/*.lo
 	-rm -f ldap/servers/plugins/views/*.$(OBJEXT)
 	-rm -f ldap/servers/plugins/views/*.lo
-	-rm -f ldap/servers/plugins/whoami/*.$(OBJEXT)
-	-rm -f ldap/servers/plugins/whoami/*.lo
 	-rm -f ldap/servers/slapd/*.$(OBJEXT)
 	-rm -f ldap/servers/slapd/*.lo
 	-rm -f ldap/servers/slapd/back-ldbm/*.$(OBJEXT)
@@ -5204,6 +5225,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/schema_reload/$(DEPDIR)/libschemareload_plugin_la-schema_reload.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/statechange/$(DEPDIR)/libstatechange_plugin_la-statechange.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_persist.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_refresh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-bin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-bitstring.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-ces.Plo@am__quote@
@@ -5232,7 +5257,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn_cleanup.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/views/$(DEPDIR)/libviews_plugin_la-views.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/whoami/$(DEPDIR)/libwhoami_plugin_la-whoami.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/ldap_agent_bin-agtmmap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-add.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-agtmmap.Plo@am__quote@
@@ -6442,6 +6466,34 @@ ldap/servers/plugins/collation/libcollation_plugin_la-orfilter.lo: ldap/servers/
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcollation_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/collation/libcollation_plugin_la-orfilter.lo `test -f 'ldap/servers/plugins/collation/orfilter.c' || echo '$(srcdir)/'`ldap/servers/plugins/collation/orfilter.c
 
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo: ldap/servers/plugins/sync/sync_init.c
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo -MD -MP -MF ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_init.Tpo -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo `test -f 'ldap/servers/plugins/sync/sync_init.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_init.c
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_init.Tpo ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_init.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/sync/sync_init.c' object='ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_init.lo `test -f 'ldap/servers/plugins/sync/sync_init.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_init.c
+
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo: ldap/servers/plugins/sync/sync_util.c
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo -MD -MP -MF ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_util.Tpo -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo `test -f 'ldap/servers/plugins/sync/sync_util.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_util.c
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_util.Tpo ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_util.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/sync/sync_util.c' object='ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_util.lo `test -f 'ldap/servers/plugins/sync/sync_util.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_util.c
+
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo: ldap/servers/plugins/sync/sync_refresh.c
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo -MD -MP -MF ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_refresh.Tpo -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo `test -f 'ldap/servers/plugins/sync/sync_refresh.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_refresh.c
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_refresh.Tpo ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_refresh.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/sync/sync_refresh.c' object='ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_refresh.lo `test -f 'ldap/servers/plugins/sync/sync_refresh.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_refresh.c
+
+ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo: ldap/servers/plugins/sync/sync_persist.c
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo -MD -MP -MF ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_persist.Tpo -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo `test -f 'ldap/servers/plugins/sync/sync_persist.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_persist.c
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_persist.Tpo ldap/servers/plugins/sync/$(DEPDIR)/libcontentsync_plugin_la-sync_persist.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/sync/sync_persist.c' object='ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcontentsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/sync/libcontentsync_plugin_la-sync_persist.lo `test -f 'ldap/servers/plugins/sync/sync_persist.c' || echo '$(srcdir)/'`ldap/servers/plugins/sync/sync_persist.c
+
 ldap/servers/plugins/cos/libcos_plugin_la-cos.lo: ldap/servers/plugins/cos/cos.c
 @am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcos_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/cos/libcos_plugin_la-cos.lo -MD -MP -MF ldap/servers/plugins/cos/$(DEPDIR)/libcos_plugin_la-cos.Tpo -c -o ldap/servers/plugins/cos/libcos_plugin_la-cos.lo `test -f 'ldap/servers/plugins/cos/cos.c' || echo '$(srcdir)/'`ldap/servers/plugins/cos/cos.c
 @am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/cos/$(DEPDIR)/libcos_plugin_la-cos.Tpo ldap/servers/plugins/cos/$(DEPDIR)/libcos_plugin_la-cos.Plo
@@ -8136,13 +8188,6 @@ ldap/servers/plugins/views/libviews_plugin_la-views.lo: ldap/servers/plugins/vie
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libviews_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/views/libviews_plugin_la-views.lo `test -f 'ldap/servers/plugins/views/views.c' || echo '$(srcdir)/'`ldap/servers/plugins/views/views.c
 
-ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo: ldap/servers/plugins/whoami/whoami.c
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwhoami_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo -MD -MP -MF ldap/servers/plugins/whoami/$(DEPDIR)/libwhoami_plugin_la-whoami.Tpo -c -o ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo `test -f 'ldap/servers/plugins/whoami/whoami.c' || echo '$(srcdir)/'`ldap/servers/plugins/whoami/whoami.c
-@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/whoami/$(DEPDIR)/libwhoami_plugin_la-whoami.Tpo ldap/servers/plugins/whoami/$(DEPDIR)/libwhoami_plugin_la-whoami.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/whoami/whoami.c' object='ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwhoami_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/whoami/libwhoami_plugin_la-whoami.lo `test -f 'ldap/servers/plugins/whoami/whoami.c' || echo '$(srcdir)/'`ldap/servers/plugins/whoami/whoami.c
-
 ldap/servers/slapd/tools/dbscan_bin-dbscan.o: ldap/servers/slapd/tools/dbscan.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dbscan_bin_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/tools/dbscan_bin-dbscan.o -MD -MP -MF ldap/servers/slapd/tools/$(DEPDIR)/dbscan_bin-dbscan.Tpo -c -o ldap/servers/slapd/tools/dbscan_bin-dbscan.o `test -f 'ldap/servers/slapd/tools/dbscan.c' || echo '$(srcdir)/'`ldap/servers/slapd/tools/dbscan.c
 @am__fastdepCC_TRUE@	$(am__mv) ldap/servers/slapd/tools/$(DEPDIR)/dbscan_bin-dbscan.Tpo ldap/servers/slapd/tools/$(DEPDIR)/dbscan_bin-dbscan.Po
@@ -9314,11 +9359,11 @@ clean-libtool:
 	-rm -rf ldap/servers/plugins/rootdn_access/.libs ldap/servers/plugins/rootdn_access/_libs
 	-rm -rf ldap/servers/plugins/schema_reload/.libs ldap/servers/plugins/schema_reload/_libs
 	-rm -rf ldap/servers/plugins/statechange/.libs ldap/servers/plugins/statechange/_libs
+	-rm -rf ldap/servers/plugins/sync/.libs ldap/servers/plugins/sync/_libs
 	-rm -rf ldap/servers/plugins/syntaxes/.libs ldap/servers/plugins/syntaxes/_libs
 	-rm -rf ldap/servers/plugins/uiduniq/.libs ldap/servers/plugins/uiduniq/_libs
 	-rm -rf ldap/servers/plugins/usn/.libs ldap/servers/plugins/usn/_libs
 	-rm -rf ldap/servers/plugins/views/.libs ldap/servers/plugins/views/_libs
-	-rm -rf ldap/servers/plugins/whoami/.libs ldap/servers/plugins/whoami/_libs
 	-rm -rf ldap/servers/slapd/.libs ldap/servers/slapd/_libs
 	-rm -rf ldap/servers/slapd/back-ldbm/.libs ldap/servers/slapd/back-ldbm/_libs
 	-rm -rf lib/base/.libs lib/base/_libs
@@ -10028,6 +10073,8 @@ distclean-generic:
 	-rm -f ldap/servers/plugins/schema_reload/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/statechange/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/statechange/$(am__dirstamp)
+	-rm -f ldap/servers/plugins/sync/$(DEPDIR)/$(am__dirstamp)
+	-rm -f ldap/servers/plugins/sync/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/syntaxes/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/syntaxes/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/uiduniq/$(DEPDIR)/$(am__dirstamp)
@@ -10036,8 +10083,6 @@ distclean-generic:
 	-rm -f ldap/servers/plugins/usn/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/views/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ldap/servers/plugins/views/$(am__dirstamp)
-	-rm -f ldap/servers/plugins/whoami/$(DEPDIR)/$(am__dirstamp)
-	-rm -f ldap/servers/plugins/whoami/$(am__dirstamp)
 	-rm -f ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ldap/servers/slapd/$(am__dirstamp)
 	-rm -f ldap/servers/slapd/back-ldbm/$(DEPDIR)/$(am__dirstamp)
@@ -10076,7 +10121,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/posix-winsync/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/plugins/whoami/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+	-rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/posix-winsync/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/sync/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
@@ -10132,7 +10177,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/posix-winsync/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/plugins/whoami/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+	-rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/posix-winsync/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/sync/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/ldap/admin/src/scripts/50contentsync.ldif b/ldap/admin/src/scripts/50contentsync.ldif
new file mode 100644
index 0000000..2864bce
--- /dev/null
+++ b/ldap/admin/src/scripts/50contentsync.ldif
@@ -0,0 +1,13 @@
+dn: cn=Content Synchronization,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+cn: Content Synchronization
+nsslapd-pluginpath: libcontentsync-plugin
+nsslapd-plugininitfunc: sync_init
+nsslapd-plugintype: object
+nsslapd-pluginenabled: off
+# these will be replaced when the server loads the plugin
+nsslapd-pluginId: ID
+nsslapd-pluginVersion: PACKAGE_VERSION
+nsslapd-pluginVendor: VENDOR
+nsslapd-pluginDescription: DESC
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index 189c4aa..03ad5ec 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -656,6 +656,18 @@ nsslapd-plugintype: betxnpreoperation
 nsslapd-pluginenabled: on
 nsslapd-plugin-depends-on-type: database
 
+dn: cn=Content Synchronization,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+objectclass: extensibleObject
+cn: Content Synchronization
+nsslapd-pluginpath: libcontentsync-plugin
+nsslapd-plugininitfunc: sync_init
+nsslapd-plugintype: object
+nsslapd-pluginenabled: off
+nsslapd-pluginbetxn: on
+nsslapd-plugin-depends-on-type: database
+
 dn: cn=deref,cn=plugins,cn=config
 objectclass: top
 objectclass: nsSlapdPlugin
diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
new file mode 100644
index 0000000..d3aeebc
--- /dev/null
+++ b/ldap/servers/plugins/sync/sync.h
@@ -0,0 +1,168 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ * 
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception. 
+ * 
+ * 
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+/**
+ * LDAP content synchronization plug-in
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "slapi-plugin.h"
+
+#define PLUGIN_NAME              "content-sync-plugin"
+
+#define SYNC_PLUGIN_SUBSYSTEM      "content-sync-plugin"
+#define SYNC_PREOP_DESC		"content-sync-preop-subplugin"
+#define SYNC_POSTOP_DESC		"content-sync-postop-subplugin"
+
+#define LDAP_CONTROL_CONTENT_SYNCHRONIZATION "1.3.6.1.4.1.4203.1.9.1.1"
+#define OP_FLAG_SYNC_PERSIST 0x01
+
+#define E_SYNC_REFRESH_REQUIRED 0x1000
+
+#define CL_ATTR_CHANGENUMBER "changenumber"
+#define CL_ATTR_ENTRYDN "targetDn"
+#define CL_SRCH_BASE "cn=changelog"
+
+typedef struct sync_cookie {
+	char *cookie_client_signature;
+	char *cookie_server_signature;
+	char *cookie_change_info;
+} Sync_Cookie;
+
+typedef struct sync_callback {
+	Slapi_PBlock *orig_pb;
+	char * changenr;
+	int err;
+} Sync_CallBackData;
+
+int sync_register_operation_extension(void);
+
+int sync_srch_refresh_pre_search(Slapi_PBlock *pb);
+int sync_srch_refresh_pre_entry(Slapi_PBlock *pb);
+int sync_srch_refresh_pre_result(Slapi_PBlock *pb);
+int sync_del_persist_post_op(Slapi_PBlock *pb);
+int sync_mod_persist_post_op(Slapi_PBlock *pb);
+int sync_modrdn_persist_post_op(Slapi_PBlock *pb);
+int sync_add_persist_post_op(Slapi_PBlock *pb);
+
+int sync_parse_control_value( struct berval *psbvp, ber_int_t *mode, int *reload, char **cookie );
+int sync_create_state_control( Slapi_Entry *e, LDAPControl **ctrlp, int type, char *cookie);
+int sync_intermediate_msg (Slapi_PBlock *pb, Sync_Cookie *cookie);
+
+Sync_Cookie *sync_cookie_create (Slapi_PBlock *pb);
+Sync_Cookie *sync_cookie_parse (char *cookie);
+int sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie);
+void sync_cookie_free (Sync_Cookie **freecookie);
+
+int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb);
+
+int sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie);
+int sync_refresh_initial_content(Slapi_PBlock *pb);
+int sync_send_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data);
+
+int sync_persist_initialize ();
+PRThread *sync_persist_add (Slapi_PBlock *pb);
+int sync_persist_startup (PRThread *tid);
+int sync_persist_terminate_all ();
+int sync_persist_terminate (PRThread *tid);
+
+Slapi_PBlock *sync_pblock_copy(Slapi_PBlock *src);
+
+/* prototype for functions not in slapi-plugin.h */
+Slapi_ComponentId *plugin_get_default_component_id();
+
+
+/*
+ * Structures to handle the persitent phase of 
+ * Content Synchronization Requests
+ *
+ * A queue of entries being to be sent by a particular persistent
+ * sync thread
+ *
+ * will be created in post op plugins 
+ */
+typedef struct sync_queue_node {
+	Slapi_Entry			*sync_entry;
+	LDAPControl			*pe_ctrls[2]; /* XXX ?? XXX */
+	struct sync_queue_node	*sync_next;
+	int 			sync_chgtype;
+} SyncQueueNode;
+
+/*
+ * Information about a single sync search
+ *
+ * will be created when a content sync control with 
+ * mode == 3 is decoded
+ */
+typedef struct sync_request {
+    Slapi_PBlock	*req_pblock;
+    PRLock		*req_lock;
+    PRThread		*req_tid;
+	char 		*req_orig_base;
+	Slapi_Filter	*req_filter;
+    PRInt32		req_complete;
+    SyncQueueNode		*ps_eq_head;
+    SyncQueueNode		*ps_eq_tail;
+    time_t		ps_lasttime; /* XXX ?? XXX */
+    ber_int_t		ps_changetypes; /* XXX ?? XXX */
+    int			req_active;
+    struct sync_request	*req_next;
+} SyncRequest;
+
+/*
+ * A list of established persistent synchronization searches.
+ *
+ * will be initialized at plugin initialization
+ */
+typedef struct sync_request_list {
+    Slapi_RWLock	*sync_req_rwlock;	/* R/W lock struct to serialize access */
+    SyncRequest	*sync_req_head;	/* Head of list */
+    PRLock	*sync_req_cvarlock;	/* Lock for cvar */
+    PRCondVar	*sync_req_cvar;	/* ps threads sleep on this */
+} SyncRequestList;
+
+
+typedef struct sync_op_info {
+    int send_flag; /* hint for preop plugins what to send */
+    char *cookie; /* cookie to add in control */
+} SyncOpInfo;
+
diff --git a/ldap/servers/plugins/sync/sync_init.c b/ldap/servers/plugins/sync/sync_init.c
new file mode 100644
index 0000000..6c94cff
--- /dev/null
+++ b/ldap/servers/plugins/sync/sync_init.c
@@ -0,0 +1,161 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ * 
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception. 
+ * 
+ * 
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "sync.h"
+
+static Slapi_PluginDesc pdesc = { PLUGIN_NAME, VENDOR, DS_PACKAGE_VERSION, "Context Synchronization (RFC4533) plugin" };
+
+static int sync_start(Slapi_PBlock * pb);
+static int sync_close(Slapi_PBlock * pb);
+static int sync_preop_init( Slapi_PBlock *pb );
+static int sync_postop_init( Slapi_PBlock *pb );
+
+int sync_init( Slapi_PBlock *pb )
+{
+    char *plugin_identity = NULL;
+	int rc = 0;
+
+    slapi_log_error(SLAPI_LOG_TRACE, SYNC_PLUGIN_SUBSYSTEM,
+                    "--> sync_init\n");
+
+    /**
+     * Store the plugin identity for later use.
+     * Used for internal operations
+     */
+
+    slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
+    PR_ASSERT(plugin_identity);
+
+    if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
+                         SLAPI_PLUGIN_VERSION_01) != 0 ||
+        slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
+                         (void *) sync_start) != 0 ||
+        slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
+                         (void *) sync_close) != 0 ||
+        slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
+                         (void *) &pdesc) != 0 )
+    {
+        slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM,
+                        "sync_init: failed to register plugin\n");
+	rc = 1;
+    }
+
+    if (rc == 0) {
+        char *plugin_type = "preoperation";
+        /* the config change checking post op */
+        if (slapi_register_plugin(plugin_type, 
+                                  1,        /* Enabled */
+                                  "sync_init",   /* this function desc */
+                                  sync_preop_init,  /* init func for post op */
+                                  SYNC_PREOP_DESC,      /* plugin desc */
+                                  NULL,     /* ? */
+                                  plugin_identity   /* access control */
+                                  )) {
+            slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM,
+                            "sync_init: failed to register preop plugin\n");
+            rc = 1;
+        }
+    }
+
+    if (rc == 0) {
+        char *plugin_type = "postoperation";
+        /* the config change checking post op */
+        if (slapi_register_plugin(plugin_type, 
+                                  1,        /* Enabled */
+                                  "sync_init",   /* this function desc */
+                                  sync_postop_init,  /* init func for post op */
+                                  SYNC_POSTOP_DESC,      /* plugin desc */
+                                  NULL,     /* ? */
+                                  plugin_identity   /* access control */
+                                  )) {
+            slapi_log_error(SLAPI_LOG_FATAL, SYNC_PLUGIN_SUBSYSTEM,
+                            "sync_init: failed to register postop plugin\n");
+            rc = 1;
+        }
+    }
+
+	return( rc );
+}
+
+static int
+sync_preop_init( Slapi_PBlock *pb )
+{
+        slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_SEARCH_FN, (void *) sync_srch_refresh_pre_search);
+        slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ENTRY_FN, (void *) sync_srch_refresh_pre_entry);
+        slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_RESULT_FN, (void *) sync_srch_refresh_pre_result);
+        sync_register_operation_extension();
+}
+
+static int
+sync_postop_init( Slapi_PBlock *pb )
+{
+        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, (void *) sync_add_persist_post_op);
+        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *) sync_del_persist_post_op);
+        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *) sync_mod_persist_post_op);
+        slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *) sync_modrdn_persist_post_op);
+}
+
+/*
+	sync_start
+	--------------
+	Register the Content Synchronization Control.
+	Initialize locks and queues for the persitent phase.
+*/
+static int
+sync_start(Slapi_PBlock * pb)
+{
+	slapi_register_supported_control( LDAP_CONTROL_CONTENT_SYNCHRONIZATION,
+        	SLAPI_OPERATION_SEARCH );
+	slapi_log_error(SLAPI_LOG_TRACE, SYNC_PLUGIN_SUBSYSTEM,
+		"--> sync_start\n");
+
+	sync_persist_initialize();
+
+	return (0);
+}
+
+/*
+	sync_close
+	--------------
+	Free locks and queues allocated.
+*/
+static int
+sync_close(Slapi_PBlock * pb)
+{
+	sync_persiste_terminate_all();
+    return (0);
+}
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
new file mode 100644
index 0000000..86e4000
--- /dev/null
+++ b/ldap/servers/plugins/sync/sync_persist.c
@@ -0,0 +1,701 @@
+/** BEGIN COPYRIGHT BLOCK
+ent sync_srch_refresh_pre_op(Slapi_PBlock *pb);
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ * 
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception. 
+ * 
+ * 
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "sync.h"
+
+/* Main list of established persistent synchronizaton searches */
+static SyncRequestList	*sync_request_list = NULL;
+/*
+ * Convenience macros for locking the list of persistent searches
+ */
+#define SYNC_LOCK_READ()    slapi_rwlock_rdlock(sync_request_list->sync_req_rwlock)
+#define SYNC_UNLOCK_READ()  slapi_rwlock_unlock(sync_request_list->sync_req_rwlock)
+#define SYNC_LOCK_WRITE()   slapi_rwlock_wrlock(sync_request_list->sync_req_rwlock)
+#define SYNC_UNLOCK_WRITE() slapi_rwlock_unlock(sync_request_list->sync_req_rwlock)
+    
+/*
+ * Convenience macro for checking if the Content Synchronization subsystem has
+ * been initialized.
+ */
+#define SYNC_IS_INITIALIZED()	(sync_request_list != NULL)
+
+
+static void sync_add_request( SyncRequest *req );
+static void sync_remove_request( SyncRequest *req );
+static SyncRequest *sync_request_alloc();
+void sync_queue_change( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype );
+static void sync_send_results( void *arg );
+static void sync_request_wakeup_all();
+static void sync_node_free( SyncQueueNode **node );
+
+static int sync_acquire_connection (Slapi_Connection *conn);
+static int sync_release_connection (Slapi_Connection *conn);
+
+int sync_add_persist_post_op(Slapi_PBlock *pb)
+{
+	Slapi_Entry *e;
+
+	if ( !SYNC_IS_INITIALIZED()) {
+		return(0);
+	}
+	slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
+	sync_queue_change(e, NULL, LDAP_REQ_ADD);
+	return( 0 );
+}
+
+int sync_del_persist_post_op(Slapi_PBlock *pb)
+{
+	Slapi_Entry *e;
+
+	if ( !SYNC_IS_INITIALIZED()) {
+		return(0);
+	}
+	slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
+	sync_queue_change(e, NULL, LDAP_REQ_DELETE);
+	return( 0 );
+}
+
+int sync_mod_persist_post_op(Slapi_PBlock *pb)
+{
+	Slapi_Entry *e;
+
+	if ( !SYNC_IS_INITIALIZED()) {
+		return(0);
+	}
+	slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
+	sync_queue_change(e, NULL, LDAP_REQ_MODIFY);
+	return( 0 );
+}
+
+int sync_modrdn_persist_post_op(Slapi_PBlock *pb)
+{
+	Slapi_Entry *e, *e_prev;
+
+	if ( !SYNC_IS_INITIALIZED()) {
+		return(0);
+	}
+	slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
+	slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e_prev);
+	sync_queue_change(e, e_prev, LDAP_REQ_MODRDN);
+	return( 0 );
+}
+
+void
+sync_queue_change( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype )
+{
+	SyncRequest	*req = NULL;
+	SyncQueueNode *node = NULL;
+	int  matched = 0;
+	const char *edn;
+
+	if ( !SYNC_IS_INITIALIZED()) {
+		return;
+	}
+
+	if ( NULL == e ) {
+		/* For now, some backends such as the chaining backend do not provide a post-op entry */
+		return;
+	}
+
+	SYNC_LOCK_READ();
+	edn = slapi_entry_get_dn_const(e);
+
+	for ( req = sync_request_list->sync_req_head; NULL != req; req = req->req_next ) {
+		char *origbase = NULL;
+		Slapi_DN *base = NULL;
+		Slapi_Filter	*f;
+		int		scope;
+		Slapi_Operation *op;
+
+		/* Skip the nodes that have no more active operation 
+		 */
+		slapi_pblock_get( req->req_pblock, SLAPI_OPERATION, &op );
+		if ( op == NULL || slapi_op_abandoned( req->req_pblock ) ) {
+			continue;
+		}
+
+/*		slapi_log_error(SLAPI_LOG_CONNS, "Synchronization Request",
+						"conn=%" NSPRIu64 " op=%d entry %s with chgtype %d "
+						"matches the ps changetype %d\n",
+						ps->req_pblock->pb_conn->c_connid,
+						ps->req_pblock->pb_op->o_opid,
+						edn, chgtype, ps->ps_changetypes);
+*/
+		slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_TARGET_SDN, &base );
+		slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_SCOPE, &scope );
+		if (NULL == base) {
+			base = slapi_sdn_new_dn_byref(req->req_orig_base);
+			slapi_pblock_set(req->req_pblock, SLAPI_SEARCH_TARGET_SDN, base);
+		}
+
+		/*
+		 * See if the entry meets the scope and filter criteria.
+		 * We cannot do the acl check here as this thread
+		 * would then potentially clash with the ps_send_results()
+		 * thread on the aclpb in ps->req_pblock.
+		 * By avoiding the acl check in this thread, and leaving all the acl
+		 * checking to the ps_send_results() thread we avoid
+		 * the req_pblock contention problem.
+		 * The lesson here is "Do not give multiple threads arbitary access
+		 * to the same pblock" this kind of muti-threaded access
+		 * to the same pblock must be done carefully--there is currently no
+		 * generic satisfactory way to do this.
+		*/
+		if ( slapi_sdn_scope_test( slapi_entry_get_sdn_const(e), base, scope ) &&
+			 slapi_vattr_filter_test( req->req_pblock, e, req->req_filter, 0 /* verify_access */ ) == 0 ) {
+			SyncQueueNode *pOldtail;
+
+			/* The scope and the filter match - enqueue it */
+
+			matched++;
+			node = (SyncQueueNode *)slapi_ch_calloc( 1, sizeof( SyncQueueNode ));
+			node->sync_entry = slapi_entry_dup( e );
+			node->sync_chgtype = chgtype;
+
+			/* Put it on the end of the list for this sync search */
+			PR_Lock( req->req_lock );
+			pOldtail = req->ps_eq_tail;
+			req->ps_eq_tail = node;
+			if ( NULL == req->ps_eq_head ) {
+				req->ps_eq_head = req->ps_eq_tail;
+			}
+			else {
+				pOldtail->sync_next = req->ps_eq_tail;
+			}
+			PR_Unlock( req->req_lock );
+		}
+	}
+
+   	SYNC_UNLOCK_READ();
+
+	/* Were there any matches? */
+	if ( matched ) {
+		/* Turn 'em loose */
+		sync_request_wakeup_all();
+/*		LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: enqueued entry "
+			"\"%s\" on %d persistent search lists\n", slapi_entry_get_dn_const(e), matched, 0 );
+*/
+	} else {
+/*		LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: entry "
+			"\"%s\" not enqueued on any persistent search lists\n", slapi_entry_get_dn_const(e), 0, 0 );
+*/
+	}
+
+}
+/*
+ * Initialize the list structure which contains the list
+ * established content sync persistent requests
+ */
+int
+sync_persist_initialize ()
+{
+    if ( !SYNC_IS_INITIALIZED()) {
+	sync_request_list = (SyncRequestList *) slapi_ch_calloc( 1, sizeof( SyncRequestList ));
+	if (( sync_request_list->sync_req_rwlock = slapi_new_rwlock()) == NULL ) {
+/*	    LDAPDebug( LDAP_DEBUG_ANY, "init_sync_request_list: cannot initialize lock structure. "
+		    "The server is terminating.\n", 0, 0, 0 );
+*/
+	    return( -1 );
+	}
+	if (( sync_request_list->sync_req_cvarlock = PR_NewLock()) == NULL ) {
+/*	    LDAPDebug( LDAP_DEBUG_ANY, "init_sync_request_list: cannot create new lock.  "
+		    "The server is terminating.\n", 0, 0, 0 );
+*/
+	    return( -1 );
+	}
+	if (( sync_request_list->sync_req_cvar = PR_NewCondVar( sync_request_list->sync_req_cvarlock )) == NULL ) {
+/*	    LDAPDebug( LDAP_DEBUG_ANY, "init_sync_request_list: cannot create new condition variable.  "
+		    "The server is terminating.\n", 0, 0, 0 );
+*/
+	    return( -1 );
+	}
+	sync_request_list->sync_req_head = NULL;
+    }
+	return (0);
+}
+/*
+ * Add the given pblock to the list of established sync searches.
+ * Then, start a thread to send the results to the client as they
+ * are dispatched by add, modify, and modrdn operations.
+ */
+PRThread *
+sync_persist_add (Slapi_PBlock *pb)
+{
+	int rc = 0;
+	SyncRequest *req = NULL;
+	char *base;
+	Slapi_Filter *filter;
+
+    if ( SYNC_IS_INITIALIZED() && NULL != pb ) {
+	/* Create the new node */
+	req = sync_request_alloc();
+	req->req_pblock = sync_pblock_copy(pb);
+	slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &base);
+	req->req_orig_base = slapi_ch_strdup(base);
+	slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter );
+	req->req_filter = slapi_filter_dup(filter);
+
+	/* Add it to the head of the list of persistent searches */
+	sync_add_request( req );
+
+	/* Start a thread to send the results */
+	req->req_tid = PR_CreateThread( PR_USER_THREAD, sync_send_results,
+		(void *) req, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+		PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE );
+
+        /* Checking if the thread is succesfully created and 
+         * if the thread is not created succesfully.... we send 
+         * error messages to the Log file 
+         */ 
+       if(NULL == (req->req_tid)){ 
+            int prerr;
+            prerr = PR_GetError(); 
+/*            LDAPDebug(LDAP_DEBUG_ANY,"persistent search PR_CreateThread()failed in the " 
+                     "ps_add function: " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
+					 prerr, slapd_pr_strerror(prerr), 0); 
+*/ 
+         /* Now remove the ps from the list so call the function ps_remove */ 
+            sync_remove_request(req); 
+            PR_DestroyLock ( req->req_lock );
+            req->req_lock = NULL;
+            slapi_ch_free((void **) &req->req_pblock );
+            slapi_ch_free((void **) &req );
+          } else {
+		return( req->req_tid);
+	}
+    }
+	return( NULL);
+}
+
+int
+sync_persist_startup (PRThread *tid)
+{
+	SyncRequest *cur;
+	int rc = 1;
+
+	if ( SYNC_IS_INITIALIZED() && NULL != tid ) {
+		SYNC_LOCK_READ();
+		/* Find and change */
+	  	cur = sync_request_list->sync_req_head;
+	  	while ( NULL != cur ) {
+			if ( cur->req_tid == tid ) {
+				cur->req_active = PR_TRUE;
+				rc = 0;
+				break;
+			}
+			cur = cur->req_next;
+		}
+		SYNC_UNLOCK_READ();
+	}
+	return (rc);
+}
+
+
+int
+sync_persist_terminate (PRThread *tid)
+{
+	SyncRequest *cur;
+	int rc = 1;
+
+	if ( SYNC_IS_INITIALIZED() && NULL != tid ) {
+		SYNC_LOCK_READ();
+		/* Find and change */
+	  	cur = sync_request_list->sync_req_head;
+	  	while ( NULL != cur ) {
+			if ( cur->req_tid == tid ) {
+				cur->req_active = PR_TRUE;
+				rc = 0;
+				break;
+			}
+			cur = cur->req_next;
+		}
+		SYNC_UNLOCK_READ();
+	}
+	if (rc == 0)
+		sync_remove_request(cur);
+	return(rc);
+}
+int
+sync_persist_terminate_all ()
+{
+	SyncRequest *cur;
+
+	if ( SYNC_IS_INITIALIZED() ) {
+		SYNC_LOCK_READ();
+	  	cur = sync_request_list->sync_req_head;
+	  	while ( NULL != cur ) {
+			cur->req_complete = PR_TRUE;
+			cur = cur->req_next;
+		}
+		SYNC_UNLOCK_READ();
+	}
+
+	return (0);
+}
+
+/*
+ * Allocate and initialize an empty Sync node.
+ */
+static SyncRequest *
+sync_request_alloc()
+{
+	SyncRequest *req;
+
+	req = (SyncRequest *) slapi_ch_calloc( 1, sizeof( SyncRequest ));
+
+	req->req_pblock = NULL;
+	if (( req->req_lock = PR_NewLock()) == NULL ) {
+/*	LDAPDebug( LDAP_DEBUG_ANY, "psearch_add: cannot create new lock.  "
+		"Persistent search abandoned.\n", 0, 0, 0 );
+*/
+		slapi_ch_free((void **)&req);
+		return( NULL );
+	}
+	req->req_tid = (PRThread *) NULL;
+	req->req_complete = 0;
+	req->ps_eq_head = req->ps_eq_tail = (SyncQueueNode *) NULL;
+	req->ps_lasttime = (time_t) 0L;
+	req->req_next = NULL;
+	req->req_active = PR_FALSE;
+	return req;
+}
+
+
+
+/*
+ * Add the given persistent search to the
+ * head of the list of persistent searches.
+ */
+static void
+sync_add_request( SyncRequest *req )
+{
+    if ( SYNC_IS_INITIALIZED() && NULL != req ) {
+		SYNC_LOCK_WRITE();
+		req->req_next = sync_request_list->sync_req_head;
+		sync_request_list->sync_req_head = req;
+		SYNC_UNLOCK_WRITE();
+    }
+}
+
+static void
+sync_remove_request( SyncRequest *req )
+{
+  SyncRequest	*cur;
+  
+  if ( SYNC_IS_INITIALIZED() && NULL != req ) {
+	SYNC_LOCK_WRITE();
+	if ( req == sync_request_list->sync_req_head ) {
+	  /* Remove from head */
+	  sync_request_list->sync_req_head = sync_request_list->sync_req_head->req_next;
+	} else {
+	  /* Find and remove from list */
+	  cur = sync_request_list->sync_req_head;
+	  while ( NULL != cur->req_next ) {
+		if ( cur->req_next == req ) {
+		  cur->req_next = cur->req_next->req_next;
+		  break;
+		} else {
+		  cur = cur->req_next;
+		}
+	  }
+	}
+	SYNC_UNLOCK_WRITE();
+  }
+}
+static void
+sync_request_wakeup_all()
+{
+	if ( SYNC_IS_INITIALIZED()) {
+		PR_Lock( sync_request_list->sync_req_cvarlock );
+		PR_NotifyAllCondVar( sync_request_list->sync_req_cvar );
+		PR_Unlock( sync_request_list->sync_req_cvarlock );
+	}
+}
+static int
+sync_acquire_connection (Slapi_Connection *conn)
+{
+	/* need to acquire a reference to this connection so that it will not
+	   be released or cleaned up out from under us 
+
+	   in psearch.c it is implemented as:
+		PR_Lock( ps->req_pblock->pb_conn->c_mutex );
+		conn_acq_flag = connection_acquire_nolock(ps->req_pblock->pb_conn);    
+    		PR_Unlock( ps->req_pblock->pb_conn->c_mutex );
+
+
+	HOW TO DO FROM A PLUGIN
+	- either expose the functions from the connection code in the private api
+	  and allow to link them in
+	- or fake a connection structure
+		struct fake_conn {
+			void	*needed1
+			void	*needed2
+			void	*pad1
+			void	*pad2
+			void	*needed3;
+		}
+		struct fake_conn *c = (struct fake_conn *) conn;
+		c->needed3 ++;
+		this would require knowledge or analysis of the connection structure,
+		could probably be done for servers with a common history
+	*/
+	return (0);
+}
+
+static int
+sync_release_connection (Slapi_Connection *conn)
+{
+	/* see comments in sync_acquire_connection */
+
+	/* code from psearch as reference */
+#if 0
+    conn = ps->req_pblock->pb_conn; /* save to release later - connection_remove_operation_ext will NULL the pb_conn */
+    /* Clean up the connection structure */
+    PR_Lock( conn->c_mutex );
+
+	slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
+					"conn=%" NSPRIu64 " op=%d Releasing the connection and operation\n",
+					conn->c_connid, ps->req_pblock->pb_op->o_opid);
+    /* Delete this op from the connection's list */
+    connection_remove_operation_ext( ps->req_pblock, conn, ps->req_pblock->pb_op );
+
+    /* Decrement the connection refcnt */
+    if (conn_acq_flag == 0) { /* we acquired it, so release it */
+	connection_release_nolock (conn);
+    }
+    PR_Unlock( conn->c_mutex );
+    conn = NULL;
+#endif
+
+	return(0);
+}
+/*
+ * Thread routine for sending search results to a client
+ * which is persistently waiting for them.
+ *
+ * This routine will terminate when either (a) the ps_complete
+ * flag is set, or (b) the associated operation is abandoned.
+ * In any case, the thread won't notice until it wakes from
+ * sleeping on the ps_list condition variable, so it needs
+ * to be awakened.
+ */
+static void
+sync_send_results( void *arg )
+{
+	SyncRequest *req = (SyncRequest *)arg;
+	SyncQueueNode *qnode, *qnodenext;
+	struct slapi_filter *filter = 0;
+	char *base = NULL;
+	Slapi_DN *sdn = NULL;
+	char *fstr = NULL;
+	char **pbattrs = NULL;
+	int conn_acq_flag = 0;
+	Slapi_Connection *conn = NULL;
+    
+
+
+	slapi_pblock_get(req->req_pblock, SLAPI_CONNECTION, &conn);
+	conn_acq_flag = sync_acquire_connection (conn);
+	if (conn_acq_flag) {
+		int connid;
+		int opid;
+		slapi_pblock_get(req->req_pblock, SLAPI_CONN_ID, &connid);
+		slapi_pblock_get(req->req_pblock, SLAPI_OPERATION_ID, &opid);
+		slapi_log_error(SLAPI_LOG_FATAL, "Content Synchronization Search",
+						"conn=%" NSPRIu64 " op=%d Could not acquire the connection - aborted\n",
+						connid, opid);
+	}
+
+    PR_Lock( sync_request_list->sync_req_cvarlock );
+
+    while ( (conn_acq_flag == 0) && !req->req_complete ) {
+	/* Check for an abandoned operation */
+	Slapi_Operation *op;
+	slapi_pblock_get(req->req_pblock, SLAPI_OPERATION, &op);
+	if ( op == NULL || slapi_op_abandoned( req->req_pblock ) ) {
+/*		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
+						"conn=%" NSPRIu64 " op=%d The operation has been abandoned\n",
+						ps->req_pblock->pb_conn->c_connid, ps->req_pblock->pb_op->o_opid);
+*/
+	    break;
+	}
+	if ( NULL == req->ps_eq_head || !req->req_active) {
+	    /* Nothing to do */
+	    /* If an operation is abandoned, we do not get notified by the
+		 * connection code. Wake up every second toc check if thread
+		 * should terminate.
+		 */ 
+	    PR_WaitCondVar( sync_request_list->sync_req_cvar, PR_SecondsToInterval(1) );
+	} else {
+	    /* dequeue the item */
+	    int		attrsonly;
+	    char	**attrs;
+	    LDAPControl	**ectrls = NULL;
+	    Slapi_Entry	*ec;
+		int chg_type;
+		
+		/* deque one element */
+		PR_Lock( req->req_lock );
+		qnode = req->ps_eq_head;
+		req->ps_eq_head = qnode->sync_next;
+		if ( NULL == req->ps_eq_head ) {
+			req->ps_eq_tail = NULL;
+		}
+		PR_Unlock( req->req_lock );
+
+		/* Get all the information we need to send the result */
+		ec = qnode->sync_entry;
+		slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_ATTRS, &attrs );
+		slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
+
+	    /*
+	     * Send the result.  Since send_ldap_search_entry can block for
+	     * up to 30 minutes, we relinquish all locks before calling it.
+	     */
+	    PR_Unlock(sync_request_list->sync_req_cvarlock);
+
+		/*
+		 * The entry is in the right scope and matches the filter
+		 * but we need to redo the filter test here to check access
+		 * controls. See the comments at the slapi_filter_test()
+		 * call in ps_service_persistent_searches().		 
+		*/
+
+		/* See if the entry meets the filter and ACL criteria */
+		if ( slapi_vattr_filter_test( req->req_pblock, ec, req->req_filter,
+			    1 /* verify_access */ ) == 0 ) {
+			int rc = 0;
+	    	slapi_pblock_set( req->req_pblock, SLAPI_SEARCH_RESULT_ENTRY, ec );
+
+		/* NEED TO BUILD THE CONTROL */
+		switch (qnode->sync_chgtype){ 
+			case LDAP_REQ_ADD:
+				chg_type = LDAP_SYNC_ADD;
+				break;
+			case LDAP_REQ_MODIFY:
+				chg_type = LDAP_SYNC_MODIFY;
+				break;
+			case LDAP_REQ_MODRDN:
+				chg_type = LDAP_SYNC_MODIFY;
+				break;
+			case LDAP_REQ_DELETE:
+				chg_type = LDAP_SYNC_DELETE;
+				attrs = slapi_ch_calloc(2, sizeof (char *));
+                		attrs[0] = slapi_ch_strdup("1.1");
+                		attrs[1] = NULL;
+				break;
+		}
+		ectrls = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
+		sync_create_state_control(ec, &ectrls[0], chg_type, NULL);
+	    	rc = slapi_send_ldap_search_entry( req->req_pblock, ec,
+										 ectrls, attrs, attrsonly );
+/*			if (rc) {
+				slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
+								"conn=%" NSPRIu64 " op=%d Error %d sending entry %s with op status %d\n",
+								ps->req_pblock->pb_conn->c_connid, ps->req_pblock->pb_op->o_opid,
+								rc, slapi_entry_get_dn_const(ec), ps->req_pblock->pb_op->o_status);
+			}
+*/	    
+		}
+		PR_Lock(sync_request_list->sync_req_cvarlock);
+
+		/* Deallocate our wrapper for this entry */
+		sync_node_free( &qnode );
+	}
+    }
+    PR_Unlock( sync_request_list->sync_req_cvarlock );
+    sync_remove_request( req );
+
+    /* indicate the end of search */
+
+/* WHY 
+    plugin_call_plugins( ps->req_pblock , SLAPI_PLUGIN_POST_SEARCH_FN );
+*/
+	/* free things from the pblock that were not free'd in do_search() */
+	/* we strdup'd this in search.c - need to free */
+/*	slapi_pblock_get( req->req_pblock, SLAPI_ORIGINAL_TARGET_DN, &base );
+	slapi_pblock_set( req->req_pblock, SLAPI_ORIGINAL_TARGET_DN, NULL );
+	slapi_ch_free_string(&base);
+
+	slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_TARGET_SDN, &sdn );
+	slapi_pblock_set( req->req_pblock, SLAPI_SEARCH_TARGET_SDN, NULL );
+	slapi_sdn_free(&sdn);
+
+    slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_STRFILTER, &fstr );
+    slapi_pblock_set( req->req_pblock, SLAPI_SEARCH_STRFILTER, NULL );
+	slapi_ch_free_string(&fstr);
+
+    slapi_pblock_get( req->req_pblock, SLAPI_SEARCH_ATTRS, &pbattrs );
+    slapi_pblock_set( req->req_pblock, SLAPI_SEARCH_ATTRS, NULL );
+	if ( pbattrs != NULL )
+	{
+		slapi_ch_array_free( pbattrs );
+	}
+	
+	slapi_pblock_get(req->req_pblock, SLAPI_SEARCH_FILTER, &filter );
+	slapi_pblock_set(req->req_pblock, SLAPI_SEARCH_FILTER, NULL );
+	slapi_filter_free(filter, 1);
+*/
+	sync_release_connection(conn);
+
+    PR_DestroyLock ( req->req_lock );
+    req->req_lock = NULL;
+
+    slapi_ch_free((void **) &req->req_pblock );
+	for ( qnode = req->ps_eq_head; qnode; qnode = qnodenext) {
+		qnodenext = qnode->sync_next;
+		sync_node_free( &qnode );
+	}
+    slapi_ch_free((void **) &req );
+}
+
+
+/*
+ * Free a sync update node (and everything it holds).
+ */
+static void
+sync_node_free( SyncQueueNode **node )
+{
+	if ( node != NULL && *node != NULL ) {
+		if ( (*node)->sync_entry != NULL ) {
+			slapi_entry_free( (*node)->sync_entry );
+			(*node)->sync_entry = NULL;
+		}
+		slapi_ch_free( (void **)node );
+	}
+}
diff --git a/ldap/servers/plugins/sync/sync_refresh.c b/ldap/servers/plugins/sync/sync_refresh.c
new file mode 100644
index 0000000..be67373
--- /dev/null
+++ b/ldap/servers/plugins/sync/sync_refresh.c
@@ -0,0 +1,318 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ * 
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception. 
+ * 
+ * 
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "sync.h"
+
+static SyncOpInfo *new_SyncOpInfo(int flag, char *cookie);
+
+static int sync_extension_type;
+static int sync_extension_handle;
+
+static const SyncOpInfo *sync_get_operation_extension(Slapi_PBlock *pb);
+static void sync_set_operation_extension(Slapi_PBlock *pb, SyncOpInfo *spec);
+
+int sync_srch_refresh_pre_search(Slapi_PBlock *pb)
+{
+
+	LDAPControl **requestcontrols;
+	struct berval	*psbvp;
+	Sync_Cookie *client_cookie = NULL;
+	Sync_Cookie *current_cookie = NULL;
+	int 	rc = 0;
+	int sync_persist = 0;
+	PRThread *tid = NULL;
+	int entries_sent = 0;
+
+	slapi_pblock_get (pb, SLAPI_REQCONTROLS, &requestcontrols);
+	if ( slapi_control_present( requestcontrols, LDAP_CONTROL_CONTENT_SYNCHRONIZATION, &psbvp, NULL )){
+		char *cookie = NULL;
+		int mode = 1;
+		int refresh = 0;
+
+		if ( sync_parse_control_value( psbvp, &mode,
+									 &refresh, &cookie ) != LDAP_SUCCESS )
+		{
+			/* operation_set_flag(operation, OP_FLAG_SYNC_REFRESHONLY); */
+		}
+		else if ( mode == 1 || mode == 3 )
+		{
+
+			/* we need to return a cookie in the result message
+			 * indicating a state to be used in future sessions
+			 * as starting point - create it now
+			 */
+			current_cookie = sync_cookie_create(pb);
+			/*
+			 *  if mode is persist we need to setup the persit handler
+			 * to catch the mods while the refresh is done 
+			 */
+			if ( mode == 3 )
+			{
+				tid = sync_persist_add(pb);
+				if ( tid ) 
+					sync_persist = 1;
+				else 
+					goto error_return;
+			}
+			/* 
+			 * now handl the refresh request
+			 * there are two scenarios
+			 * 1. no cookie is provided this means send all entries matching the search request
+			 * 2. a cookie is provided: send all entries changed since the cookie was issued
+			 * 	-- return an error if the cookie is invalid
+			 * 	-- return e-syncRefreshRequired if the data referenced in the cookie are no
+			 * 		longer in the history
+			*/
+			if (cookie) {
+				client_cookie = sync_cookie_parse (cookie);
+				if (sync_cookie_isvalid(client_cookie, current_cookie)) {
+					rc = sync_refresh_update_content(pb, client_cookie);
+					if (rc == 0) 
+						entries_sent = 1;
+					rc = sync_intermediate_msg(pb, current_cookie);
+				} else {
+					rc = E_SYNC_REFRESH_REQUIRED;
+				}
+			} else {
+				rc = sync_refresh_initial_content (pb);
+			}
+			
+			if ( rc ) {
+				if (sync_persist)
+					sync_persist_terminate (tid);
+				goto error_return;
+			} else if (sync_persist){
+				Slapi_Operation *operation;
+
+				slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
+				rc = sync_persist_startup(tid);
+				if (rc == 0)
+					operation_set_flag(operation, OP_FLAG_SYNC_PERSIST);
+			}
+			
+
+		} else {
+			/* unknown mode, return an error */
+			rc = 1;
+		}
+	}
+
+error_return:
+	sync_cookie_free(&client_cookie);
+	sync_cookie_free(&current_cookie);
+	/* if we sent the entries
+	 * return "error" to abort normal search
+	 */ 
+	if ( rc > 0 || entries_sent > 0 )
+		return(1);
+	else
+		return(0);
+}
+
+int sync_srch_refresh_pre_entry(Slapi_PBlock *pb)
+{
+	Slapi_Operation *op;
+	const SyncOpInfo *info = sync_get_operation_extension(pb);
+
+    if (!info) {
+        return 0; /* nothing to do */
+    }
+
+	slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+	return(0);
+}
+
+int sync_srch_refresh_pre_result(Slapi_PBlock *pb)
+{
+	Slapi_Operation *op;
+	const SyncOpInfo *info = sync_get_operation_extension(pb);
+
+	if (!info) {
+		return 0; /* nothing to do */
+	}
+	if (info->send_flag == 2)
+		return(1);
+	else
+		return(0);
+}
+
+int
+sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie)
+{
+	Slapi_PBlock *seq_pb;
+	char *filter;
+	Sync_CallBackData cb_data;
+	int rc;
+
+	seq_pb = slapi_pblock_new();
+	slapi_pblock_init(seq_pb);
+
+	cb_data.orig_pb = pb;
+
+	filter = slapi_ch_smprintf("changenumber>=%s",client_cookie->cookie_change_info);
+	slapi_search_internal_set_pb(
+		seq_pb, 
+		CL_SRCH_BASE,
+		LDAP_SCOPE_ONE,
+		filter,
+		NULL,
+		0,
+		NULL, NULL, 
+		plugin_get_default_component_id(),
+		0);							  
+
+	rc = slapi_search_internal_callback_pb (
+		seq_pb, &cb_data, NULL, sync_send_entry_from_changelog, NULL);
+	slapi_pblock_destroy(seq_pb);
+
+	return (rc);
+}
+
+int
+sync_refresh_initial_content(Slapi_PBlock *pb)
+{
+	/* the entries will be sent in the normal search process, but
+	 * - a control has to be sent with each entry
+	 * - an intermediate response has to be sent
+	 * - no result message must be sent
+	 *
+	 *   setup on operation extension to take care of in 
+	 *   pre_entry, pre_result and post_search plugins
+	 */
+	SyncOpInfo *info = new_SyncOpInfo (2, NULL);
+	sync_set_operation_extension(pb, info);
+     
+	return(0);
+}
+
+sync_send_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data)
+{
+	char *entrydn = NULL;
+	Slapi_Entry *db_entry;
+	Slapi_Value *sval=NULL;
+	const struct berval *value;
+	Sync_CallBackData *cb = (Sync_CallBackData *) cb_data;
+
+	if ( NULL != cl_entry ) {
+		Slapi_Attr *chattr = NULL;
+		sval = NULL;
+		value = NULL;
+		if ( slapi_entry_attr_find( cl_entry, CL_ATTR_ENTRYDN, &chattr ) == 0 ) {
+			slapi_attr_first_value( chattr,&sval );
+			if ( NULL != sval ) {
+				value = slapi_value_get_berval ( sval );
+				if( NULL != value && NULL != value->bv_val &&
+					'\0' != value->bv_val[0]) {
+					entrydn = slapi_ch_strdup( value->bv_val);
+				}
+			}
+		}
+	}
+	if (entrydn) {
+		Slapi_DN *dn = slapi_sdn_new_dn_byval(entrydn);
+		slapi_search_internal_get_entry(dn, NULL, &db_entry, plugin_get_default_component_id());
+	}
+	if (db_entry && sync_is_active(db_entry, cb->orig_pb)) {
+		LDAPControl **ctrl = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
+		sync_create_state_control(db_entry, &ctrl[0], LDAP_SYNC_PRESENT, NULL);
+		slapi_send_ldap_search_entry (cb->orig_pb, db_entry, ctrl, NULL, 0);
+	}
+}
+static SyncOpInfo*
+new_SyncOpInfo(int flag, char *cookie) {
+    SyncOpInfo *spec = (SyncOpInfo *)slapi_ch_calloc(1, sizeof(SyncOpInfo));
+    spec->send_flag = flag;
+    spec->cookie = cookie;
+
+    return spec;
+}
+/* consumer operation extension constructor */
+static void *
+sync_operation_extension_ctor(void *object, void *parent)
+{
+    /* we only set the extension value explicitly if the
+       client requested the control - see deref_pre_search */
+    return NULL; /* we don't set anything in the ctor */
+}
+
+/* consumer operation extension destructor */
+static void 
+sync_delete_SyncOpInfo(SyncOpInfo **info)
+{
+	if (info && *info) {
+		slapi_ch_free((void **)&((*info)->cookie));
+        	slapi_ch_free((void **)info);
+	}
+}
+
+static void
+sync_operation_extension_dtor(void *ext, void *object, void *parent)
+{
+   SyncOpInfo *spec = (SyncOpInfo *)ext;
+    sync_delete_SyncOpInfo(&spec);
+}
+
+static const SyncOpInfo *
+sync_get_operation_extension(Slapi_PBlock *pb)
+{
+    Slapi_Operation *op;
+
+    slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+    return (const SyncOpInfo *)slapi_get_object_extension(sync_extension_type,
+                                                             op, sync_extension_handle);
+}
+
+static void
+sync_set_operation_extension(Slapi_PBlock *pb, SyncOpInfo *spec)
+{
+    Slapi_Operation *op;
+
+    slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+    slapi_set_object_extension(sync_extension_type, op,
+                               sync_extension_handle, (void *)spec);
+}
+
+int
+sync_register_operation_extension(void)
+{
+	return slapi_register_object_extension(SYNC_PLUGIN_SUBSYSTEM,
+                                           SLAPI_EXT_OPERATION, 
+                                           sync_operation_extension_ctor,
+                                           sync_operation_extension_dtor,
+                                           &sync_extension_type,
+                                           &sync_extension_handle);
+}
diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c
new file mode 100644
index 0000000..fce813c
--- /dev/null
+++ b/ldap/servers/plugins/sync/sync_util.c
@@ -0,0 +1,423 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ * 
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ * 
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception. 
+ * 
+ * 
+ * Copyright (C) 2013 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "sync.h"
+
+static struct berval * create_syncinfo_value( int type, const char *cookie);
+static char * sync_cookie_get_server_info();
+static char * sync_cookie_get_client_info(Slapi_PBlock *pb);
+
+/*
+ * Parse the value from an LDAPv3 sync request control.  They look
+ * like this:
+ * 
+ *    syncRequestValue ::= SEQUENCE {
+ *	mode ENUMERATED {
+ *		-- 0 unused
+ *		refreshOnly	(1),
+ *		-- 2 reserved
+ *		refreshAndPersist (3)
+ *	},
+ *	cookie 		syncCookie OPTIONAL,
+ *	reloadHint	BOOLEAN DEFAULT FALSE
+ *   }
+ *
+ * Return an LDAP error code (LDAP_SUCCESS if all goes well).
+ *
+ */
+int
+sync_parse_control_value( struct berval *psbvp, ber_int_t *mode, int *reload, char **cookie )
+{
+    int rc= LDAP_SUCCESS;
+
+    if ( psbvp->bv_len == 0 || psbvp->bv_val == NULL )
+    {
+    	rc= LDAP_PROTOCOL_ERROR;
+    }
+    else
+    {
+        BerElement *ber= ber_init( psbvp );
+        if ( ber == NULL )
+        {
+        	rc= LDAP_OPERATIONS_ERROR;
+        }
+        else
+        {
+            if ( ber_scanf( ber, "{e", mode ) == LBER_ERROR )
+            {
+            	rc= LDAP_PROTOCOL_ERROR;
+            } else if ( ber_scanf( ber, "a", cookie ) != LBER_ERROR )
+            	ber_scanf( ber, "b}", reload ) == LBER_ERROR ;
+
+       	    /* the ber encoding is no longer needed */
+       	    ber_free(ber,1);
+        }
+    }
+
+    return( rc );
+}
+static void
+nsUnique_to_syncUUID (int suuid[4], char *val)
+{
+	suuid[0] = slapi_str_to_u32(val);
+	suuid[1] = slapi_str_to_u32(val+9);
+	suuid[2] = slapi_str_to_u32(val+18);
+	suuid[3] = slapi_str_to_u32(val+27);
+}
+
+/*
+ * 	syncStateValue ::= SEQUENCE {
+ * 		state ENUMERATED {
+ * 			present (0),
+ * 			add (1),
+ * 			modify (2),
+ * 			delete (3)
+ * 		},
+ * 		entryUUID syncUUID,
+ * 		cookie    syncCookie OPTIONAL
+ *	}
+ *
+ */
+int
+sync_create_state_control( Slapi_Entry *e, LDAPControl **ctrlp, int type, char *cookie)
+{
+	int		rc;
+	BerElement	*ber;
+	struct berval	*bvp;
+	char *syncUUID;
+	int sUUID[4];
+	Slapi_Attr *attr;
+	Slapi_Value *val;
+
+    if ( ctrlp == NULL || ( ber = der_alloc()) == NULL ) {
+	return( LDAP_OPERATIONS_ERROR );
+    }
+
+    *ctrlp = NULL;
+
+	slapi_entry_attr_find(e, SLAPI_ATTR_UNIQUEID, &attr);
+	slapi_attr_first_value(attr, &val);
+	nsUnique_to_syncUUID (sUUID, slapi_value_get_string(val));
+/*
+	syncUUID = slapi_ch_strdup(slapi_value_get_string(val)); 
+
+    if (( rc = ber_printf( ber, "{es", type , syncUUID )) != -1 ) {
+*/
+    if (( rc = ber_printf( ber, "{eo", type , (char *)sUUID, 16 )) != -1 ) {
+		if (cookie) 
+			rc = ber_printf( ber, "s}", cookie);
+		else
+			rc = ber_printf( ber, "}");
+	}
+	if (rc != -1) {
+	rc = ber_flatten( ber, &bvp );
+    }
+    ber_free( ber, 1 );
+
+    if ( rc == -1 ) {
+	return( LDAP_OPERATIONS_ERROR );
+    }
+
+    *ctrlp = (LDAPControl *)slapi_ch_malloc( sizeof( LDAPControl ));
+    (*ctrlp)->ldctl_iscritical = 0;
+    (*ctrlp)->ldctl_oid = slapi_ch_strdup( LDAP_CONTROL_SYNC_STATE );
+    (*ctrlp)->ldctl_value = *bvp;	/* struct copy */
+
+	bvp->bv_val = NULL;
+	ber_bvfree( bvp );
+
+}
+
+int
+sync_intermediate_msg (Slapi_PBlock *pb, Sync_Cookie *cookie)
+{
+	int rc;
+	struct berval *syncInfo;
+	LDAPControl *ctrlp = NULL;
+	char *cookiestr = NULL;
+
+	if (cookie)
+		cookiestr = slapi_ch_smprintf("%s#%s#%s",
+				cookie->cookie_server_signature,
+				cookie->cookie_client_signature,
+				cookie->cookie_change_info);
+	syncInfo = create_syncinfo_value(LDAP_TAG_SYNC_REFRESH_PRESENT, cookiestr);
+
+	rc = slapi_send_ldap_intermediate( pb,  &ctrlp, "1.3.6.1.4.1.4203.1.9.1.4", syncInfo);
+	return (rc);
+}
+
+
+static struct berval *
+create_syncinfo_value( int type, const char *cookie)
+{
+    BerElement		*ber;
+    struct berval	*bvp = NULL;
+
+    if ( ( ber = der_alloc() ) == NULL ) {
+	return( NULL );
+    }
+
+	switch (type) {
+		case LDAP_TAG_SYNC_NEW_COOKIE:
+			ber_printf(ber, "to", type, cookie);
+			break;
+		case LDAP_TAG_SYNC_REFRESH_DELETE:
+		case LDAP_TAG_SYNC_REFRESH_PRESENT:
+			ber_printf(ber, "t{", type);
+			if (cookie)
+				ber_printf(ber, "sb}", cookie, 1);
+			break;
+		case LDAP_TAG_SYNC_ID_SET:
+			ber_printf(ber, "t{", type);
+			/* incopmplete */
+			break;
+		default: 
+			break;
+	}
+	ber_flatten( ber, &bvp );
+    ber_free( ber, 1 );
+
+	return( bvp );
+}
+
+static void 
+sync_handle_cnum_result(int rc, void *cb_data)
+{
+}
+
+static int 
+sync_handle_cnum_entry(Slapi_Entry *e, void *cb_data)
+{
+    Sync_CallBackData *cb = (Sync_CallBackData *)cb_data;
+    Slapi_Value *sval=NULL;
+    const struct berval *value;
+
+    cb->changenr = NULL;
+
+    if ( NULL != e ) {
+	Slapi_Attr *chattr = NULL;
+	sval = NULL;
+	value = NULL;
+	if ( slapi_entry_attr_find( e, CL_ATTR_CHANGENUMBER, &chattr ) == 0 ) {
+	    slapi_attr_first_value( chattr,&sval );
+	    if ( NULL != sval ) {
+		value = slapi_value_get_berval ( sval );
+		if( NULL != value && NULL != value->bv_val &&
+		    '\0' != value->bv_val[0]) {
+			cb->changenr = slapi_ch_strdup(value->bv_val);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * a cookie is used to synchronize client server sessions,
+ * it consist of three parts
+ * -- server id, client should only sync with one server
+ * -- client id, client should use same bind dn, and srch params 
+ * -- change info, kind of state info like csn, ruv, 
+ *  	in the first implementation use changenumber from retro cl
+ *
+ * syntax: <server-id>#<client-id>#change
+ *
+ */
+static char *
+ sync_cookie_get_server_info()
+{
+	return(slapi_ch_strdup("localhost:port:whatelse"));
+}
+
+static char *
+sync_cookie_get_client_info(Slapi_PBlock *pb)
+{
+	char *dn;
+	
+	slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
+	return (slapi_ch_strdup(dn));
+}
+
+Sync_Cookie *
+sync_cookie_create (Slapi_PBlock *pb)
+{
+
+	Slapi_PBlock *seq_pb;
+	char *base;
+	char *attrname;
+	Sync_CallBackData scbd;
+	int rc;
+	Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie));
+
+	base = slapi_ch_strdup("cn=changelog");
+	attrname = slapi_ch_strdup("changenumber");
+
+	seq_pb = slapi_pblock_new();
+	slapi_pblock_init(seq_pb);
+
+	slapi_seq_internal_set_pb(seq_pb, base, SLAPI_SEQ_LAST, attrname, NULL, NULL, 0, 0, 
+		plugin_get_default_component_id(), 0);							  
+
+	rc = slapi_seq_internal_callback_pb (seq_pb, &scbd, sync_handle_cnum_result, sync_handle_cnum_entry, NULL);
+	slapi_pblock_destroy(seq_pb);
+
+	sc->cookie_server_signature = sync_cookie_get_server_info();
+	sc->cookie_client_signature = sync_cookie_get_client_info(pb);
+	sc->cookie_change_info = scbd.changenr;
+/*    slapi_log_error(SLAPI_LOG_PLUGIN,"retrocl","Got changenumbers %l and %l\n", lastchange, rc); */
+	return (sc);
+}
+
+Sync_Cookie *
+sync_cookie_parse (char *cookie)
+{
+	char *p, *q;
+	p = q = cookie;
+	Sync_Cookie *sc = (Sync_Cookie *)slapi_ch_malloc(sizeof(Sync_Cookie));
+
+	sc->cookie_client_signature = NULL;
+	sc->cookie_server_signature = NULL;
+	sc->cookie_change_info = NULL;
+	p = strchr(q, '#');
+	if (p) {
+		*p = '\0';
+		sc->cookie_server_signature = slapi_ch_strdup(q);
+		q = p + 1;
+		p = strchr(q, '#');
+		if (p) {
+			*p = '\0';
+			sc->cookie_client_signature = slapi_ch_strdup(q);
+			sc->cookie_change_info = slapi_ch_strdup(p+1);
+		}
+	}
+		
+	return (sc);
+}
+
+int
+sync_cookie_isvalid (Sync_Cookie *testcookie, Sync_Cookie *refcookie)
+{
+	return (1);
+}
+
+void
+sync_cookie_free (Sync_Cookie **freecookie)
+{
+}
+
+int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb)
+{
+	int rc;
+
+	if ( pb == NULL ) {
+		/* not yet initialized */
+		rc = 0;
+	} else {
+		/* check id entry is in scope of sync request */
+		char *origbase = NULL;
+		Slapi_DN *base = NULL;
+		int		scope;
+
+		slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &origbase );
+		slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &base );
+		slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope );
+		if (NULL == base) {
+			base = slapi_sdn_new_dn_byref(origbase);
+			slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, base);
+		}
+		if ( slapi_sdn_scope_test( slapi_entry_get_sdn_const(e), base, scope ))
+			rc = 1;
+		else
+			rc = 0;
+	}
+
+	return (rc);
+}
+
+Slapi_PBlock *
+sync_pblock_copy(Slapi_PBlock *src)
+{
+	Slapi_Operation *operation;
+	Slapi_Connection *connection;
+	char *rawbase;
+	int *scope;
+	int *deref;
+	int *filter_normalized;
+	char *fstr;
+	char **attrs, **attrs_dup;
+/*	char **gerattrs;*/
+	int *attrsonly;
+	int *isroot;
+	int *sizelimit;
+	int *timelimit;
+	struct slapdplugin *pi;
+
+
+	slapi_pblock_get( src, SLAPI_OPERATION, &operation );
+	slapi_pblock_get( src, SLAPI_CONNECTION, &connection );
+	slapi_pblock_get( src, SLAPI_SEARCH_SCOPE, &scope );
+	slapi_pblock_get( src, SLAPI_SEARCH_DEREF, &deref );
+	slapi_pblock_get( src, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
+	slapi_pblock_get( src, SLAPI_SEARCH_STRFILTER, &fstr );
+	slapi_pblock_get( src, SLAPI_SEARCH_ATTRS, &attrs );
+/*	slapi_pblock_get( src, SLAPI_SEARCH_GERATTRS, &gerattrs );*/
+	slapi_pblock_get( src, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
+	slapi_pblock_get( src, SLAPI_REQUESTOR_ISROOT, &isroot );
+	slapi_pblock_get( src, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
+	slapi_pblock_get( src, SLAPI_SEARCH_TIMELIMIT, &timelimit );
+	slapi_pblock_get( src, SLAPI_PLUGIN, &pi);
+
+	Slapi_PBlock *dest = slapi_pblock_new();
+
+	slapi_pblock_set( dest, SLAPI_OPERATION, operation );
+	slapi_pblock_set( dest, SLAPI_CONNECTION, connection );
+	slapi_pblock_set( dest, SLAPI_SEARCH_SCOPE, &scope );
+	slapi_pblock_set( dest, SLAPI_SEARCH_DEREF, &deref );
+	slapi_pblock_set( dest, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
+	slapi_pblock_set( dest, SLAPI_SEARCH_STRFILTER, slapi_ch_strdup(fstr) );
+	attrs_dup = slapi_ch_array_dup(attrs);
+	slapi_pblock_set( dest, SLAPI_SEARCH_ATTRS, attrs_dup );
+/*	slapi_pblock_set( dest, SLAPI_SEARCH_GERATTRS, gerattrs );*/
+	slapi_pblock_set( dest, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
+	slapi_pblock_set( dest, SLAPI_REQUESTOR_ISROOT, &isroot );
+	slapi_pblock_set( dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
+	slapi_pblock_set( dest, SLAPI_SEARCH_TIMELIMIT, &timelimit );
+	slapi_pblock_set( dest, SLAPI_PLUGIN, pi);
+
+	return dest;
+}
+
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index d374883..706ff5a 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -2994,7 +2994,12 @@ connection_abandon_operations( Connection *c )
 		/* abandon the operation only if it is not yet
 		   completed (i.e., no result has been sent yet to 
 		   the client */
-		if ( op->o_status != SLAPI_OP_STATUS_RESULT_SENT ) {
+		/* sync repl uses the persist mode, and it cannot prevent
+		 * setting o_status, but has to be abandonned
+		 * handle it here until a better solution is found
+		 */	
+		if ( op->o_status != SLAPI_OP_STATUS_RESULT_SENT ||
+			op->o_flags & OP_FLAG_PS ) {
 			op->o_status = SLAPI_OP_STATUS_ABANDONED;
 		}
 	}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 5430a1c..843e33b 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -591,6 +591,15 @@ plugin_get_pwd_storage_scheme_list(int index)
 	return( names_list );
 }
 
+int slapi_send_ldap_intermediate( Slapi_PBlock *pb, LDAPControl **ectrls,
+	char *responseName, struct berval *responseValue)
+{
+	/* no SLAPI_PLUGIN_DB_INTERMEDIATE_FN defined
+	 * always directly call slapd_ function
+	 */
+	return send_ldap_intermediate(pb, ectrls, responseName, responseValue);
+}
+
 int
 slapi_send_ldap_search_entry( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **ectrls,
 	char **attrs, int attrsonly )
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index e0c1a4e..33d895e 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -954,6 +954,8 @@ int send_ldap_search_entry_ext( Slapi_PBlock *pb, Slapi_Entry *e, LDAPControl **
 	char **attrs, int attrsonly, int send_result, int nentries, struct berval **urls );
 void send_ldap_result_ext( Slapi_PBlock *pb, int err, char *matched, char *text,
 	int nentries, struct berval **urls, BerElement	*ber );
+int send_ldap_intermediate( Slapi_PBlock *pb, LDAPControl **ectrls,
+	char *responseName, struct berval *responseValue);
 void send_nobackend_ldap_result( Slapi_PBlock *pb );
 int send_ldap_referral( Slapi_PBlock *pb, Slapi_Entry *e, struct berval **refs,
 	struct berval ***urls );
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 9b6fb8b..c72a0ea 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -223,6 +223,71 @@ send_ldap_result(
        send_ldap_result_ext(pb, err, matched, text, nentries, urls, NULL);
 }
 
+int send_ldap_intermediate( Slapi_PBlock *pb,  LDAPControl **ectrls,
+	char *responseName, struct berval *responseValue)
+{
+	ber_tag_t	tag;
+	BerElement	*ber;
+	Slapi_Connection *connection;
+	Slapi_Operation	*operation;
+	int 		rc;
+	int		logit = 0;
+			
+	LDAPDebug( LDAP_DEBUG_TRACE, "=> send_ldap_intermediate\n", 0, 0, 0 );
+	slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
+	slapi_pblock_get (pb, SLAPI_CONNECTION, &connection);
+
+	if (operation->o_status == SLAPI_OP_STATUS_RESULT_SENT) {
+		return; /* result already sent */
+	}
+	tag = LDAP_RES_INTERMEDIATE;
+	if ( (ber = der_alloc()) == NULL ) {
+		LDAPDebug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
+		goto log_and_return;
+	}
+	/* add the intermediate message */
+	rc = ber_printf( ber, "{it{", operation->o_msgid, tag);
+	/* print responsename */
+	rc = ber_printf ( ber, "ts", LDAP_TAG_IM_RES_OID, responseName);
+	/* print responsevalue */
+	rc = ber_printf ( ber, "tO", LDAP_TAG_IM_RES_VALUE, responseValue);
+
+
+
+	if ( rc != LBER_ERROR ) {
+		rc = ber_printf( ber, "}" ); /* one more } to come */
+	}
+
+	if ( ectrls != NULL 
+	    && connection->c_ldapversion >= LDAP_VERSION3
+	    && write_controls( ber, ectrls ) != 0 ) {
+		rc = (int)LBER_ERROR;
+	}
+
+	if ( rc != LBER_ERROR ) {	/* end the LDAPMessage sequence */
+		rc = ber_put_seq( ber );
+	}
+	if ( rc == LBER_ERROR ) {
+		LDAPDebug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+		ber_free( ber, 1 /* freebuf */ );
+		goto log_and_return;
+	}
+
+	/* write only one pdu at a time - wait til it's our turn */
+	if ( flush_ber( pb, connection, operation, ber, _LDAP_SEND_RESULT ) == 0 ) {
+		logit = 1;
+	}
+log_and_return:
+	operation->o_status = SLAPI_OP_STATUS_RESULT_SENT;	/* in case this has not yet been set */
+
+	if ( logit && operation_is_flag_set( operation,
+	    OP_FLAG_ACTION_LOG_ACCESS )) {
+		log_result( pb, operation, rc, tag, 0 );
+	}
+
+	LDAPDebug( LDAP_DEBUG_TRACE, "<= send_ldap_intermediate\n", 0, 0, 0 );
+
+}
 
 static int
 check_and_send_extended_result(Slapi_PBlock *pb, ber_tag_t tag, BerElement *ber)
@@ -1554,7 +1619,7 @@ send_ldap_search_entry_ext(
 	}
 	
 	/* if the client explicitly specified a list of attributes look through each attribute requested */
-	if( (rc == 0) && (attrs!=NULL)) {
+	if( (rc == 0) && (attrs!=NULL) && !noattrs) {
 		rc = send_specific_attrs(e,attrs,op,pb,ber,attrsonly,conn->c_ldapversion,dontsendattr,real_attrs_only);
 	}
 
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8309012..c848153 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5072,6 +5072,8 @@ void slapi_send_ldap_result( Slapi_PBlock *pb, int err, char *matched,
 	char *text, int nentries, struct berval **urls );
 int slapi_send_ldap_referral( Slapi_PBlock *pb, Slapi_Entry *e,
 	struct berval **refs, struct berval ***urls );
+int slapi_send_ldap_intermediate( Slapi_PBlock *pb, LDAPControl **ectrls,
+	char *responseName, struct berval *responseValue);
 typedef int (*send_ldap_search_entry_fn_ptr_t)( Slapi_PBlock *pb,
 	Slapi_Entry *e, LDAPControl **ectrls, char **attrs, int attrsonly );
 typedef void (*send_ldap_result_fn_ptr_t)( Slapi_PBlock *pb, int err,
-- 
1.7.11.7

