From 5f99f7c991e57cb305c4d2871fbe84dbb6eebb0e Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Sat, 27 Nov 2004 00:57:37 +0000
Subject: [PATCH] More migration of syncrepl from frontend to syncprov overlay
 define OPERATION_BUFFER_SIZE for dummy Operations

---
 servers/slapd/back-bdb/init.c     |   2 +-
 servers/slapd/back-monitor/init.c |  61 ++---
 servers/slapd/backglue.c          |   2 +
 servers/slapd/connection.c        |  13 +-
 servers/slapd/controls.c          | 109 +--------
 servers/slapd/ldapsync.c          | 230 ------------------
 servers/slapd/operation.c         |   4 +-
 servers/slapd/overlays/pcache.c   |  19 +-
 servers/slapd/overlays/syncprov.c | 381 +++++++++++++++++++++++++++++-
 servers/slapd/proto-slap.h        |  13 -
 servers/slapd/search.c            |   6 +-
 servers/slapd/sessionlog.c        |   2 +-
 servers/slapd/slap.h              |  14 +-
 servers/slapd/slapacl.c           |  17 +-
 servers/slapd/slapauth.c          |  21 +-
 servers/slapd/syncrepl.c          |  29 +--
 16 files changed, 463 insertions(+), 460 deletions(-)

diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index 4be2ebcbea..3f7dd504e2 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -630,7 +630,7 @@ bdb_back_initialize(
 
 	bi->bi_op_unbind = 0;
 
-#if 0
+#if 0	/* DELETE ME */
 	bi->bi_op_abandon = bdb_abandon;
 	bi->bi_op_cancel = bdb_cancel;
 #endif
diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c
index 496d5e9ce8..1966e7e04a 100644
--- a/servers/slapd/back-monitor/init.c
+++ b/servers/slapd/back-monitor/init.c
@@ -373,8 +373,8 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter,
 		struct berval *ndn )
 {
 	Connection	conn = { 0 };
-	Operation	op = { 0 };
-	Opheader	ohdr = { 0 };
+	char opbuf[OPERATION_BUFFER_SIZE];
+	Operation	*op;
 	SlapReply	rs = { 0 };
 	slap_callback	cb = { NULL, monitor_filter2ndn_cb, NULL, NULL };
 	AttributeName	anlist[ 2 ];
@@ -386,52 +386,53 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter,
 		return -1;
 	}
 
-	connection_fake_init( &conn, &op, &ohdr, &conn );
+	op = (Operation *)opbuf;
+	connection_fake_init( &conn, op, &conn );
 
-	op.o_tag = LDAP_REQ_SEARCH;
+	op->o_tag = LDAP_REQ_SEARCH;
 
 	/* use global malloc for now */
-	op.o_tmpmemctx = NULL;
-	op.o_tmpmfuncs = &ch_mfuncs;
+	op->o_tmpmemctx = NULL;
+	op->o_tmpmfuncs = &ch_mfuncs;
 
-	op.o_bd = be_monitor;
+	op->o_bd = be_monitor;
 	if ( base == NULL || BER_BVISNULL( base ) ) {
-		ber_dupbv_x( &op.o_req_dn, &op.o_bd->be_suffix[ 0 ],
-				op.o_tmpmemctx );
-		ber_dupbv_x( &op.o_req_ndn, &op.o_bd->be_nsuffix[ 0 ],
-				op.o_tmpmemctx );
+		ber_dupbv_x( &op->o_req_dn, &op->o_bd->be_suffix[ 0 ],
+				op->o_tmpmemctx );
+		ber_dupbv_x( &op->o_req_ndn, &op->o_bd->be_nsuffix[ 0 ],
+				op->o_tmpmemctx );
 
 	} else {
-		if ( dnPrettyNormal( NULL, base, &op.o_req_dn, &op.o_req_ndn,
-					op.o_tmpmemctx ) ) {
+		if ( dnPrettyNormal( NULL, base, &op->o_req_dn, &op->o_req_ndn,
+					op->o_tmpmemctx ) ) {
 			/* error */
 		}
 	}
 
-	op.o_callback = &cb;
+	op->o_callback = &cb;
 	cb.sc_private = (void *)ndn;
 
-	op.ors_scope = scope;
-	ber_dupbv_x( &op.ors_filterstr, filter, op.o_tmpmemctx );
-	op.ors_filter = str2filter_x( &op, filter->bv_val );
-	op.ors_attrs = anlist;
+	op->ors_scope = scope;
+	ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
+	op->ors_filter = str2filter_x( op, filter->bv_val );
+	op->ors_attrs = anlist;
 	BER_BVSTR( &anlist[ 0 ].an_name, LDAP_NO_ATTRS );
 	BER_BVZERO( &anlist[ 1 ].an_name );
-	op.ors_attrsonly = 0;
-	op.ors_tlimit = SLAP_NO_LIMIT;
-	op.ors_slimit = 1;
-	op.ors_limit = NULL;
-	op.ors_deref = LDAP_DEREF_NEVER;
+	op->ors_attrsonly = 0;
+	op->ors_tlimit = SLAP_NO_LIMIT;
+	op->ors_slimit = 1;
+	op->ors_limit = NULL;
+	op->ors_deref = LDAP_DEREF_NEVER;
 
-	op.o_nocaching = 1;
-	op.o_managedsait = 1;
+	op->o_nocaching = 1;
+	op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
 
-	rc = op.o_bd->be_search( &op, &rs );
+	rc = op->o_bd->be_search( op, &rs );
 
-	filter_free_x( &op, op.ors_filter );
-	op.o_tmpfree( op.ors_filterstr.bv_val, op.o_tmpmemctx );
-	op.o_tmpfree( op.o_req_dn.bv_val, op.o_tmpmemctx );
-	op.o_tmpfree( op.o_req_ndn.bv_val, op.o_tmpmemctx );
+	filter_free_x( op, op->ors_filter );
+	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 
 	if ( rc != 0 ) {
 		return rc;
diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c
index f65ee40f47..064c237810 100644
--- a/servers/slapd/backglue.c
+++ b/servers/slapd/backglue.c
@@ -289,6 +289,7 @@ glue_back_search ( Operation *op, SlapReply *rs )
 	case LDAP_SCOPE_SUBORDINATE: /* FIXME */
 #endif
 
+#if 0	/* DELETE ME - verify ITS first */
 		if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
 			if (op->o_bd && op->o_bd->be_search) {
 				rs->sr_err = op->o_bd->be_search( op, rs );
@@ -298,6 +299,7 @@ glue_back_search ( Operation *op, SlapReply *rs )
 			}
 			return rs->sr_err;
 		}
+#endif
 
 		op->o_callback = &cb;
 		rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM;
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 19143d5daa..43987952e8 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -1068,21 +1068,21 @@ operations_error:
 
 	ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
 
+#if 0	/* DELETE ME */
 	if ( op->o_cancel != SLAP_CANCEL_ACK &&
 		( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
 	{
 		slap_sl_mem_detach( ctx, memctx );
-
-#if 0
 	} else if ( op->o_sync_slog_size != -1 ) {
 		slap_sl_mem_detach( ctx, memctx );
 		LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
 		LDAP_STAILQ_NEXT(op, o_next) = NULL;
 		conn->c_n_ops_executing--;
 		conn->c_n_ops_completed++;
-#endif
 
-	} else {
+	} else
+#endif
+	{
 		LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
 		LDAP_STAILQ_NEXT(op, o_next) = NULL;
 		slap_op_free( op );
@@ -1695,7 +1695,6 @@ void
 connection_fake_init(
 	Connection *conn,
 	Operation *op,
-	Opheader *ohdr,
 	void *ctx )
 {
 	conn->c_connid = -1;
@@ -1706,7 +1705,9 @@ connection_fake_init(
 	conn->c_peer_domain = slap_empty_bv;
 	conn->c_peer_name = slap_empty_bv;
 
-	op->o_hdr = ohdr;
+	memset(op, 0, OPERATION_BUFFER_SIZE);
+	op->o_hdr = (Opheader *)(op+1);
+	op->o_controls = (void **)(op->o_hdr+1);
 	/* set memory context */
 	op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx);
 	op->o_tmpmfuncs = &slap_sl_mfuncs;
diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c
index c386fcc9e9..5ccca5b4ad 100644
--- a/servers/slapd/controls.c
+++ b/servers/slapd/controls.c
@@ -41,7 +41,6 @@ static SLAP_CTRL_PARSE_FN parseSearchOptions;
 #ifdef LDAP_CONTROL_SUBENTRIES
 static SLAP_CTRL_PARSE_FN parseSubentries;
 #endif
-static SLAP_CTRL_PARSE_FN parseLDAPsync;
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
@@ -139,10 +138,6 @@ static struct slap_control control_defs[] = {
  		(int)offsetof(struct slap_control_ids, sc_noOp),
 		SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, NULL,
 		parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-	{ LDAP_CONTROL_SYNC,
- 		(int)offsetof(struct slap_control_ids, sc_LDAPsync),
-		SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
-		parseLDAPsync, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef LDAP_CONTROL_MODIFY_INCREMENT
 	{ LDAP_CONTROL_MODIFY_INCREMENT,
  		(int)offsetof(struct slap_control_ids, sc_modifyIncrement),
@@ -800,10 +795,12 @@ static int parsePagedResults (
 		return LDAP_PROTOCOL_ERROR;
 	}
 
+#if 0	/* DELETE ME */
 	if ( op->o_sync != SLAP_CONTROL_NONE ) {
 		rs->sr_text = "paged results control specified with sync control";
 		return LDAP_PROTOCOL_ERROR;
 	}
+#endif
 
 	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
 		rs->sr_text = "paged results control value is empty (or absent)";
@@ -1286,105 +1283,3 @@ static int parseSearchOptions (
 }
 #endif
 
-static int parseLDAPsync (
-	Operation *op,
-	SlapReply *rs,
-	LDAPControl *ctrl )
-{
-	ber_tag_t tag;
-	BerElement *ber;
-	ber_int_t mode;
-	ber_len_t len;
-	struct slap_session_entry *se;
-	struct berval cookie = BER_BVNULL;
-	syncrepl_state *sr;
-	int rhint = 0;
-
-	if ( op->o_sync != SLAP_CONTROL_NONE ) {
-		rs->sr_text = "Sync control specified multiple times";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-	if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
-		rs->sr_text = "Sync control specified with pagedResults control";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-
-	if ( ctrl->ldctl_value.bv_len == 0 ) {
-		rs->sr_text = "Sync control value is empty (or absent)";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-	/* Parse the control value
-	 *      syncRequestValue ::= SEQUENCE {
-	 *              mode   ENUMERATED {
-	 *                      -- 0 unused
-	 *                      refreshOnly		(1),
-	 *                      -- 2 reserved
-	 *                      refreshAndPersist	(3)
-	 *              },
-	 *              cookie  syncCookie OPTIONAL
-	 *      }
-	 */
-
-	ber = ber_init( &ctrl->ldctl_value );
-	if( ber == NULL ) {
-		rs->sr_text = "internal error";
-		return LDAP_OTHER;
-	}
-
-	if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
-		rs->sr_text = "Sync control : mode decoding error";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-	switch( mode ) {
-	case LDAP_SYNC_REFRESH_ONLY:
-		mode = SLAP_SYNC_REFRESH;
-		break;
-	case LDAP_SYNC_REFRESH_AND_PERSIST:
-		mode = SLAP_SYNC_REFRESH_AND_PERSIST;
-		break;
-	default:
-		rs->sr_text = "Sync control : unknown update mode";
-		return LDAP_PROTOCOL_ERROR;
-	}
-
-	tag = ber_peek_tag( ber, &len );
-
-	if ( tag == LDAP_TAG_SYNC_COOKIE ) {
-		if (( ber_scanf( ber, /*{*/ "o", &cookie )) == LBER_ERROR ) {
-			rs->sr_text = "Sync control : cookie decoding error";
-			return LDAP_PROTOCOL_ERROR;
-		}
-	}
-	if ( tag == LDAP_TAG_RELOAD_HINT ) {
-		if (( ber_scanf( ber, /*{*/ "b", &rhint )) == LBER_ERROR ) {
-			rs->sr_text = "Sync control : rhint decoding error";
-			return LDAP_PROTOCOL_ERROR;
-		}
-	}
-	if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
-			rs->sr_text = "Sync control : decoding error";
-			return LDAP_PROTOCOL_ERROR;
-	}
-	sr = op->o_tmpcalloc( 1, sizeof(struct syncrepl_state), op->o_tmpmemctx );
-	sr->sr_rhint = rhint;
-	if (!BER_BVISNULL(&cookie)) {
-		ber_bvarray_add( &sr->sr_state.octet_str, &cookie );
-		slap_parse_sync_cookie( &sr->sr_state );
-	}
-
-	op->o_controls[slap_cids.sc_LDAPsync] = sr;
-
-	(void) ber_free( ber, 1 );
-
-	op->o_sync = ctrl->ldctl_iscritical
-		? SLAP_CONTROL_CRITICAL
-		: SLAP_CONTROL_NONCRITICAL;
-
-	op->o_sync_mode |= mode;	/* o_sync_mode shares o_sync */
-
-	return LDAP_SUCCESS;
-}
diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c
index e456ebc14f..4d6afd8e45 100644
--- a/servers/slapd/ldapsync.c
+++ b/servers/slapd/ldapsync.c
@@ -34,236 +34,6 @@ struct slap_sync_cookie_s slap_sync_cookie =
 	LDAP_STAILQ_HEAD_INITIALIZER( slap_sync_cookie );
 #endif
 
-int
-slap_build_sync_state_ctrl(
-	Operation	*op,
-	SlapReply	*rs,
-	Entry		*e,
-	int			entry_sync_state,
-	LDAPControl	**ctrls,
-	int			num_ctrls,
-	int			send_cookie,
-	struct berval	*cookie)
-{
-	Attribute* a;
-	int ret;
-	int res;
-	const char *text = NULL;
-
-	BerElementBuffer berbuf;
-	BerElement *ber = (BerElement *)&berbuf;
-
-	struct berval entryuuid_bv	= BER_BVNULL;
-
-	ber_init2( ber, 0, LBER_USE_DER );
-	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
-
-	ctrls[num_ctrls] = slap_sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx );
-
-	for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-		AttributeDescription *desc = a->a_desc;
-		if ( desc == slap_schema.si_ad_entryUUID ) {
-			entryuuid_bv = a->a_nvals[0];
-			break;
-		}
-	}
-
-	if ( send_cookie && cookie ) {
-		ber_printf( ber, "{eOON}",
-			entry_sync_state, &entryuuid_bv, cookie );
-	} else {
-		ber_printf( ber, "{eON}",
-			entry_sync_state, &entryuuid_bv );
-	}
-
-	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
-	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
-	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-	ber_free_buf( ber );
-
-	if ( ret < 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"slap_build_sync_ctrl: ber_flatten2 failed\n",
-			0, 0, 0 );
-		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-		return ret;
-	}
-
-	return LDAP_SUCCESS;
-}
-
-int
-slap_build_sync_done_ctrl(
-	Operation	*op,
-	SlapReply	*rs,
-	LDAPControl	**ctrls,
-	int			num_ctrls,
-	int			send_cookie,
-	struct berval *cookie,
-	int			refreshDeletes )
-{
-	int ret;
-	BerElementBuffer berbuf;
-	BerElement *ber = (BerElement *)&berbuf;
-
-	ber_init2( ber, NULL, LBER_USE_DER );
-	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
-
-	ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-	ber_printf( ber, "{" );
-	if ( send_cookie && cookie ) {
-		ber_printf( ber, "O", cookie );
-	}
-	if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) {
-		ber_printf( ber, "b", refreshDeletes );
-	}
-	ber_printf( ber, "N}" );	
-
-	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
-	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
-	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-	ber_free_buf( ber );
-
-	if ( ret < 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"slap_build_sync_done_ctrl: ber_flatten2 failed\n",
-			0, 0, 0 );
-		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-		return ret;
-	}
-
-	return LDAP_SUCCESS;
-}
-
-
-int
-slap_build_sync_state_ctrl_from_slog(
-	Operation	*op,
-	SlapReply	*rs,
-	struct slog_entry *slog_e,
-	int			entry_sync_state,
-	LDAPControl	**ctrls,
-	int			num_ctrls,
-	int			send_cookie,
-	struct berval	*cookie)
-{
-	Attribute* a;
-	int ret;
-	int res;
-	const char *text = NULL;
-
-	BerElementBuffer berbuf;
-	BerElement *ber = (BerElement *)&berbuf;
-
-	struct berval entryuuid_bv	= BER_BVNULL;
-
-	ber_init2( ber, NULL, LBER_USE_DER );
-	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
-
-	ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-	entryuuid_bv = slog_e->sl_uuid;
-
-	if ( send_cookie && cookie ) {
-		ber_printf( ber, "{eOON}",
-			entry_sync_state, &entryuuid_bv, cookie );
-	} else {
-		ber_printf( ber, "{eON}",
-			entry_sync_state, &entryuuid_bv );
-	}
-
-	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
-	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
-	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-	ber_free_buf( ber );
-
-	if ( ret < 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"slap_build_sync_ctrl: ber_flatten2 failed\n",
-			0, 0, 0 );
-		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-		return ret;
-	}
-
-	return LDAP_SUCCESS;
-}
-
-int
-slap_send_syncinfo(
-	Operation	*op,
-	SlapReply	*rs,
-	int			type,
-	struct berval *cookie,
-	int			refreshDone,
-	BerVarray	syncUUIDs,
-	int			refreshDeletes )
-{
-	BerElementBuffer berbuf;
-	BerElement *ber = (BerElement *)&berbuf;
-	struct berval rspdata;
-
-	int ret;
-
-	ber_init2( ber, NULL, LBER_USE_DER );
-	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
-
-	if ( type ) {
-		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, "O", cookie );
-			}
-			if ( refreshDone == 0 ) {
-				ber_printf( ber, "b", refreshDone );
-			}
-			ber_printf( ber, "N}" );
-			break;
-		case LDAP_TAG_SYNC_ID_SET:
-			ber_printf( ber, "t{", type );
-			if ( cookie ) {
-				ber_printf( ber, "O", cookie );
-			}
-			if ( refreshDeletes == 1 ) {
-				ber_printf( ber, "b", refreshDeletes );
-			}
-			ber_printf( ber, "[W]", syncUUIDs );
-			ber_printf( ber, "N}" );
-			break;
-		default:
-			Debug( LDAP_DEBUG_TRACE,
-				"slap_send_syncinfo: invalid syncinfo type (%d)\n",
-				type, 0, 0 );
-			return LDAP_OTHER;
-		}
-	}
-
-	ret = ber_flatten2( ber, &rspdata, 0 );
-
-	if ( ret < 0 ) {
-		Debug( LDAP_DEBUG_TRACE,
-			"slap_send_syncinfo: ber_flatten2 failed\n",
-			0, 0, 0 );
-		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-		return ret;
-	}
-
-	rs->sr_rspdata = &rspdata;
-	send_ldap_intermediate( op, rs );
-	rs->sr_rspdata = NULL;
-	ber_free_buf( ber );
-
-	return LDAP_SUCCESS;
-}
-
 void
 slap_compose_sync_cookie(
 	Operation *op,
diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c
index d50d89b247..b7c180e4ee 100644
--- a/servers/slapd/operation.c
+++ b/servers/slapd/operation.c
@@ -108,7 +108,7 @@ slap_op_free( Operation *op )
 	op->o_hdr = (Opheader *)(op+1);
 	op->o_controls = (void **)(op->o_hdr+1);
 
-#if 0
+#if 0	/* DELETE ME */
 	slap_sync_cookie_free( &op->o_sync_state, 0 );
 	if ( op->o_sync_csn.bv_val != NULL ) {
 		ch_free( op->o_sync_csn.bv_val );
@@ -155,7 +155,7 @@ slap_op_alloc(
 	op->o_opid = id;
 	op->o_res_ber = NULL;
 
-#if 0
+#if 0	/* DELETE ME */
 	op->o_sync_state.sid = -1;
 	op->o_sync_slog_size = -1;
 	op->o_sync_state.rid = -1;
diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c
index e4135b9822..150dca2ad9 100644
--- a/servers/slapd/overlays/pcache.c
+++ b/servers/slapd/overlays/pcache.c
@@ -1410,20 +1410,21 @@ consistency_check(
 	slap_overinst *on = rtask->arg;
 	cache_manager *cm = on->on_bi.bi_private;
 	query_manager *qm = cm->qm;
-	Operation op = {0};
-	Opheader ohdr = {0};
 	Connection conn = {0};
+	char opbuf[OPERATION_BUFFER_SIZE];
+	Operation *op;
 
 	SlapReply rs = {REP_RESULT};
 	CachedQuery* query, *query_prev;
 	int i, return_val, pause = 1;
 	QueryTemplate* templ;
 
-	connection_fake_init( &conn, &op, &ohdr, ctx );
+	op = (Operation *)opbuf;
+	connection_fake_init( &conn, op, ctx );
 
-	op.o_bd = &cm->db;
-	op.o_dn = cm->db.be_rootdn;
-	op.o_ndn = cm->db.be_rootndn;
+	op->o_bd = &cm->db;
+	op->o_dn = cm->db.be_rootdn;
+	op->o_ndn = cm->db.be_rootndn;
 
       	cm->cc_arg = arg;
 
@@ -1431,9 +1432,9 @@ consistency_check(
 		templ = qm->templates + i;
 		query = templ->query_last;
 		if ( query ) pause = 0;
-		op.o_time = slap_get_time();
+		op->o_time = slap_get_time();
 		ldap_pvt_thread_mutex_lock(&cm->remove_mutex);
-		while (query && (query->expiry_time < op.o_time)) {
+		while (query && (query->expiry_time < op->o_time)) {
 			ldap_pvt_thread_mutex_lock(&qm->lru_mutex);
 			remove_query(qm, query);
 			ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
@@ -1446,7 +1447,7 @@ consistency_check(
 			Debug( LDAP_DEBUG_ANY, "Unlock CR index = %d\n",
 					i, 0, 0 );
 			ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);
-			return_val = remove_query_data(&op, &rs, &query->q_uuid);
+			return_val = remove_query_data(op, &rs, &query->q_uuid);
 			Debug( LDAP_DEBUG_ANY, "STALE QUERY REMOVED, SIZE=%d\n",
 						return_val, 0, 0 );
 			ldap_pvt_thread_mutex_lock(&cm->cache_mutex);
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c
index 144fda6ad4..ca36a7b560 100644
--- a/servers/slapd/overlays/syncprov.c
+++ b/servers/slapd/overlays/syncprov.c
@@ -53,6 +53,21 @@ typedef struct syncops {
 
 static int	sync_cid;
 
+/* A received sync control */
+typedef struct sync_control {
+	struct sync_cookie sr_state;
+	int sr_rhint;
+} sync_control;
+
+/* o_sync_mode uses data bits of o_sync */
+#define	o_sync	o_ctrlflag[sync_cid]
+#define	o_sync_mode	o_ctrlflag[sync_cid]
+
+#define SLAP_SYNC_NONE					(LDAP_SYNC_NONE<<SLAP_CONTROL_SHIFT)
+#define SLAP_SYNC_REFRESH				(LDAP_SYNC_REFRESH_ONLY<<SLAP_CONTROL_SHIFT)
+#define SLAP_SYNC_PERSIST				(LDAP_SYNC_RESERVED<<SLAP_CONTROL_SHIFT)
+#define SLAP_SYNC_REFRESH_AND_PERSIST	(LDAP_SYNC_REFRESH_AND_PERSIST<<SLAP_CONTROL_SHIFT)
+
 #define	PS_IS_REFRESHING	0x01
 
 /* Record of which searches matched at premodify step */
@@ -90,6 +105,235 @@ typedef struct fbase_cookie {
 static AttributeName csn_anlist[2];
 static AttributeName uuid_anlist[2];
 
+static int
+syncprov_state_ctrl(
+	Operation	*op,
+	SlapReply	*rs,
+	Entry		*e,
+	int			entry_sync_state,
+	LDAPControl	**ctrls,
+	int			num_ctrls,
+	int			send_cookie,
+	struct berval	*cookie)
+{
+	Attribute* a;
+	int ret;
+	int res;
+	const char *text = NULL;
+
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+
+	struct berval entryuuid_bv	= BER_BVNULL;
+
+	ber_init2( ber, 0, LBER_USE_DER );
+	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+	ctrls[num_ctrls] = slap_sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx );
+
+	for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+		AttributeDescription *desc = a->a_desc;
+		if ( desc == slap_schema.si_ad_entryUUID ) {
+			entryuuid_bv = a->a_nvals[0];
+			break;
+		}
+	}
+
+	if ( send_cookie && cookie ) {
+		ber_printf( ber, "{eOON}",
+			entry_sync_state, &entryuuid_bv, cookie );
+	} else {
+		ber_printf( ber, "{eON}",
+			entry_sync_state, &entryuuid_bv );
+	}
+
+	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
+	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+	ber_free_buf( ber );
+
+	if ( ret < 0 ) {
+		Debug( LDAP_DEBUG_TRACE,
+			"slap_build_sync_ctrl: ber_flatten2 failed\n",
+			0, 0, 0 );
+		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+		return ret;
+	}
+
+	return LDAP_SUCCESS;
+}
+
+static int
+syncprov_done_ctrl(
+	Operation	*op,
+	SlapReply	*rs,
+	LDAPControl	**ctrls,
+	int			num_ctrls,
+	int			send_cookie,
+	struct berval *cookie,
+	int			refreshDeletes )
+{
+	int ret;
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+
+	ber_init2( ber, NULL, LBER_USE_DER );
+	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+	ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+	ber_printf( ber, "{" );
+	if ( send_cookie && cookie ) {
+		ber_printf( ber, "O", cookie );
+	}
+	if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) {
+		ber_printf( ber, "b", refreshDeletes );
+	}
+	ber_printf( ber, "N}" );	
+
+	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
+	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
+	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+	ber_free_buf( ber );
+
+	if ( ret < 0 ) {
+		Debug( LDAP_DEBUG_TRACE,
+			"syncprov_done_ctrl: ber_flatten2 failed\n",
+			0, 0, 0 );
+		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+		return ret;
+	}
+
+	return LDAP_SUCCESS;
+}
+
+
+static int
+syncprov_state_ctrl_from_slog(
+	Operation	*op,
+	SlapReply	*rs,
+	struct slog_entry *slog_e,
+	int			entry_sync_state,
+	LDAPControl	**ctrls,
+	int			num_ctrls,
+	int			send_cookie,
+	struct berval	*cookie)
+{
+	Attribute* a;
+	int ret;
+	int res;
+	const char *text = NULL;
+
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+
+	struct berval entryuuid_bv	= BER_BVNULL;
+
+	ber_init2( ber, NULL, LBER_USE_DER );
+	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+	ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+	entryuuid_bv = slog_e->sl_uuid;
+
+	if ( send_cookie && cookie ) {
+		ber_printf( ber, "{eOON}",
+			entry_sync_state, &entryuuid_bv, cookie );
+	} else {
+		ber_printf( ber, "{eON}",
+			entry_sync_state, &entryuuid_bv );
+	}
+
+	ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+	ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
+	ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+	ber_free_buf( ber );
+
+	if ( ret < 0 ) {
+		Debug( LDAP_DEBUG_TRACE,
+			"slap_build_sync_ctrl: ber_flatten2 failed\n",
+			0, 0, 0 );
+		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+		return ret;
+	}
+
+	return LDAP_SUCCESS;
+}
+
+int
+syncprov_sendinfo(
+	Operation	*op,
+	SlapReply	*rs,
+	int			type,
+	struct berval *cookie,
+	int			refreshDone,
+	BerVarray	syncUUIDs,
+	int			refreshDeletes )
+{
+	BerElementBuffer berbuf;
+	BerElement *ber = (BerElement *)&berbuf;
+	struct berval rspdata;
+
+	int ret;
+
+	ber_init2( ber, NULL, LBER_USE_DER );
+	ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+	if ( type ) {
+		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, "O", cookie );
+			}
+			if ( refreshDone == 0 ) {
+				ber_printf( ber, "b", refreshDone );
+			}
+			ber_printf( ber, "N}" );
+			break;
+		case LDAP_TAG_SYNC_ID_SET:
+			ber_printf( ber, "t{", type );
+			if ( cookie ) {
+				ber_printf( ber, "O", cookie );
+			}
+			if ( refreshDeletes == 1 ) {
+				ber_printf( ber, "b", refreshDeletes );
+			}
+			ber_printf( ber, "[W]", syncUUIDs );
+			ber_printf( ber, "N}" );
+			break;
+		default:
+			Debug( LDAP_DEBUG_TRACE,
+				"syncprov_sendinfo: invalid syncinfo type (%d)\n",
+				type, 0, 0 );
+			return LDAP_OTHER;
+		}
+	}
+
+	ret = ber_flatten2( ber, &rspdata, 0 );
+
+	if ( ret < 0 ) {
+		Debug( LDAP_DEBUG_TRACE,
+			"syncprov_sendinfo: ber_flatten2 failed\n",
+			0, 0, 0 );
+		send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+		return ret;
+	}
+
+	rs->sr_rspdata = &rspdata;
+	send_ldap_intermediate( op, rs );
+	rs->sr_rspdata = NULL;
+	ber_free_buf( ber );
+
+	return LDAP_SUCCESS;
+}
 /* syncprov_findbase:
  *   finds the true DN of the base of a search (with alias dereferencing) and
  * checks to make sure the base entry doesn't get replaced with a different
@@ -229,7 +473,7 @@ findcsn_cb( Operation *op, SlapReply *rs )
 		if ( sc->sc_private ) {
 			int i;
 			fcsn_cookie *fc = sc->sc_private;
-			syncrepl_state *srs = op->o_controls[sync_cid];
+			sync_control *srs = op->o_controls[sync_cid];
 			Attribute *a = attr_find(rs->sr_entry->e_attrs,
 				slap_schema.si_ad_entryCSN );
 			i = ber_bvcmp( &a->a_vals[0], srs->sr_state.ctxcsn );
@@ -270,7 +514,7 @@ findpres_cb( Operation *op, SlapReply *rs )
 			ret = LDAP_SUCCESS;
 			if ( pc->num == SLAP_SYNCUUID_SET_SIZE ) {
 				rs->sr_rspoid = LDAP_SYNC_INFO;
-				ret = slap_send_syncinfo( op, rs, LDAP_TAG_SYNC_ID_SET, NULL,
+				ret = syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, NULL,
 					0, pc->uuids, 0 );
 				ber_bvarray_free_x( pc->uuids, op->o_tmpmemctx );
 				pc->uuids = NULL;
@@ -283,7 +527,7 @@ findpres_cb( Operation *op, SlapReply *rs )
 		ret = rs->sr_err;
 		if ( pc->num ) {
 			rs->sr_rspoid = LDAP_SYNC_INFO;
-			ret = slap_send_syncinfo( op, rs, LDAP_TAG_SYNC_ID_SET, NULL,
+			ret = syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, NULL,
 				0, pc->uuids, 0 );
 			ber_bvarray_free_x( pc->uuids, op->o_tmpmemctx );
 			pc->uuids = NULL;
@@ -312,7 +556,7 @@ syncprov_findcsn( Operation *op, int mode )
 	fcsn_cookie fcookie;
 	fpres_cookie pcookie;
 	int locked = 0;
-	syncrepl_state *srs = op->o_controls[sync_cid];
+	sync_control *srs = op->o_controls[sync_cid];
 
 	if ( srs->sr_state.ctxcsn->bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
 		return LDAP_OTHER;
@@ -461,7 +705,7 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry *e, int mode
 	e_uuid.e_attrs = &a_uuid;
 	a_uuid.a_desc = slap_schema.si_ad_entryUUID;
 	a_uuid.a_nvals = &opc->suuid;
-	rs.sr_err = slap_build_sync_state_ctrl( &sop, &rs, &e_uuid,
+	rs.sr_err = syncprov_state_ctrl( &sop, &rs, &e_uuid,
 		mode, ctrls, 0, 1, &cookie );
 
 	rs.sr_entry = e;
@@ -803,6 +1047,8 @@ syncprov_detach_op( Operation *op, syncops *so )
 			op2->ors_attrs[i].an_name.bv_val = ptr;
 			ptr = lutil_strcopy( ptr, op->ors_attrs[i].an_name.bv_val ) + 1;
 		}
+		op2->ors_attrs[i].an_name.bv_val = NULL;
+		op2->ors_attrs[i].an_name.bv_len = 0;
 	} else {
 		ptr = (char *)(op2->o_hdr + 1);
 	}
@@ -833,7 +1079,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
 	searchstate *ss = op->o_callback->sc_private;
 	slap_overinst *on = ss->ss_on;
 	syncprov_info_t		*si = on->on_bi.bi_private;
-	syncrepl_state *srs = op->o_controls[sync_cid];
+	sync_control *srs = op->o_controls[sync_cid];
 
 	if ( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF ) {
 		int i;
@@ -847,7 +1093,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
 		rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
 			op->o_tmpmemctx );
 		rs->sr_ctrls[1] = NULL;
-		rs->sr_err = slap_build_sync_state_ctrl( op, rs, rs->sr_entry,
+		rs->sr_err = syncprov_state_ctrl( op, rs, rs->sr_entry,
 			LDAP_SYNC_ADD, rs->sr_ctrls, 0, 0, NULL );
 	} else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {
 		struct berval cookie;
@@ -861,13 +1107,13 @@ syncprov_search_response( Operation *op, SlapReply *rs )
 			rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
 				op->o_tmpmemctx );
 			rs->sr_ctrls[1] = NULL;
-			rs->sr_err = slap_build_sync_done_ctrl( op, rs, rs->sr_ctrls,
+			rs->sr_err = syncprov_done_ctrl( op, rs, rs->sr_ctrls,
 				0, 1, &cookie, LDAP_SYNC_REFRESH_PRESENTS );
 		} else {
 			int locked = 0;
 		/* It's RefreshAndPersist, transition to Persist phase */
 			rs->sr_rspoid = LDAP_SYNC_INFO;
-			slap_send_syncinfo( op, rs, rs->sr_nentries ?
+			syncprov_sendinfo( op, rs, rs->sr_nentries ?
 	 			LDAP_TAG_SYNC_REFRESH_PRESENT : LDAP_TAG_SYNC_REFRESH_DELETE,
 				&cookie, 1, NULL, 0 );
 			/* Flush any queued persist messages */
@@ -934,7 +1180,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
 	Filter *fand, *fava;
 	syncops *sop = NULL;
 	searchstate *ss;
-	syncrepl_state *srs;
+	sync_control *srs;
 
 	if ( !(op->o_sync_mode & SLAP_SYNC_REFRESH) ) return SLAP_CB_CONTINUE;
 
@@ -1007,7 +1253,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
 
 					ctrls[0] = NULL;
 					ctrls[1] = NULL;
-					slap_build_sync_done_ctrl( op, rs, ctrls, 0, 0,
+					syncprov_done_ctrl( op, rs, ctrls, 0, 0,
 						NULL, LDAP_SYNC_REFRESH_DELETES );
 					rs->sr_ctrls = ctrls;
 					rs->sr_err = LDAP_SUCCESS;
@@ -1141,8 +1387,6 @@ syncprov_db_init(
 	uuid_anlist[0].an_desc = slap_schema.si_ad_entryUUID;
 	uuid_anlist[0].an_name = slap_schema.si_ad_entryUUID->ad_cname;
 
-	sync_cid = slap_cids.sc_LDAPsync;
-
 	return 0;
 }
 
@@ -1163,6 +1407,107 @@ syncprov_db_destroy(
 	return 0;
 }
 
+static int syncprov_parseCtrl (
+	Operation *op,
+	SlapReply *rs,
+	LDAPControl *ctrl )
+{
+	ber_tag_t tag;
+	BerElement *ber;
+	ber_int_t mode;
+	ber_len_t len;
+	struct berval cookie = BER_BVNULL;
+	sync_control *sr;
+	int rhint = 0;
+
+	if ( op->o_sync != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "Sync control specified multiple times";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "Sync control specified with pagedResults control";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( ctrl->ldctl_value.bv_len == 0 ) {
+		rs->sr_text = "Sync control value is empty (or absent)";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	/* Parse the control value
+	 *      syncRequestValue ::= SEQUENCE {
+	 *              mode   ENUMERATED {
+	 *                      -- 0 unused
+	 *                      refreshOnly		(1),
+	 *                      -- 2 reserved
+	 *                      refreshAndPersist	(3)
+	 *              },
+	 *              cookie  syncCookie OPTIONAL
+	 *      }
+	 */
+
+	ber = ber_init( &ctrl->ldctl_value );
+	if( ber == NULL ) {
+		rs->sr_text = "internal error";
+		return LDAP_OTHER;
+	}
+
+	if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
+		rs->sr_text = "Sync control : mode decoding error";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	switch( mode ) {
+	case LDAP_SYNC_REFRESH_ONLY:
+		mode = SLAP_SYNC_REFRESH;
+		break;
+	case LDAP_SYNC_REFRESH_AND_PERSIST:
+		mode = SLAP_SYNC_REFRESH_AND_PERSIST;
+		break;
+	default:
+		rs->sr_text = "Sync control : unknown update mode";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	tag = ber_peek_tag( ber, &len );
+
+	if ( tag == LDAP_TAG_SYNC_COOKIE ) {
+		if (( ber_scanf( ber, /*{*/ "o", &cookie )) == LBER_ERROR ) {
+			rs->sr_text = "Sync control : cookie decoding error";
+			return LDAP_PROTOCOL_ERROR;
+		}
+	}
+	if ( tag == LDAP_TAG_RELOAD_HINT ) {
+		if (( ber_scanf( ber, /*{*/ "b", &rhint )) == LBER_ERROR ) {
+			rs->sr_text = "Sync control : rhint decoding error";
+			return LDAP_PROTOCOL_ERROR;
+		}
+	}
+	if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
+			rs->sr_text = "Sync control : decoding error";
+			return LDAP_PROTOCOL_ERROR;
+	}
+	sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );
+	sr->sr_rhint = rhint;
+	if (!BER_BVISNULL(&cookie)) {
+		ber_bvarray_add( &sr->sr_state.octet_str, &cookie );
+		slap_parse_sync_cookie( &sr->sr_state );
+	}
+
+	op->o_controls[sync_cid] = sr;
+
+	(void) ber_free( ber, 1 );
+
+	op->o_sync = ctrl->ldctl_iscritical
+		? SLAP_CONTROL_CRITICAL
+		: SLAP_CONTROL_NONCRITICAL;
+
+	op->o_sync_mode |= mode;	/* o_sync_mode shares o_sync */
+
+	return LDAP_SUCCESS;
+}
+
 /* This overlay is set up for dynamic loading via moduleload. For static
  * configuration, you'll need to arrange for the slap_overinst to be
  * initialized and registered by some other function inside slapd.
@@ -1173,6 +1518,16 @@ static slap_overinst 		syncprov;
 int
 syncprov_init()
 {
+	int rc;
+
+	rc = register_supported_control( LDAP_CONTROL_SYNC,
+		SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
+		syncprov_parseCtrl, &sync_cid );
+	if ( rc != LDAP_SUCCESS ) {
+		fprintf( stderr, "Failed to register control %d\n", rc );
+		return rc;
+	}
+
 	syncprov.on_bi.bi_type = "syncprov";
 	syncprov.on_bi.bi_db_init = syncprov_db_init;
 	syncprov.on_bi.bi_db_config = syncprov_db_config;
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 2f9bf95b22..d3e8f64c15 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -455,7 +455,6 @@ LDAP_SLAPD_F (void) connection2anonymous LDAP_P((Connection *));
 LDAP_SLAPD_F (void) connection_fake_init LDAP_P((
 	Connection *conn,
 	Operation *op,
-	Opheader *ohdr,
 	void *threadctx ));
 LDAP_SLAPD_F (void) connection_assign_nextid LDAP_P((Connection *));
 
@@ -728,18 +727,6 @@ LDAP_SLAPD_V (int)	krbv4_ldap_auth();
 /*
  * ldapsync.c
  */
-LDAP_SLAPD_F (int) slap_build_sync_state_ctrl LDAP_P((
-				Operation *, SlapReply *, Entry *, int,
-				LDAPControl **, int, int, struct berval * ));
-LDAP_SLAPD_F (int) slap_build_sync_done_ctrl LDAP_P((
-				Operation *, SlapReply *, LDAPControl **,
-				int, int, struct berval *, int ));
-LDAP_SLAPD_F (int) slap_build_sync_state_ctrl_from_slog LDAP_P((
-				Operation *, SlapReply *, struct slog_entry *, int,
-				LDAPControl **, int, int, struct berval * ));
-LDAP_SLAPD_F (int) slap_send_syncinfo LDAP_P((
-				Operation *, SlapReply *, int,
-				struct berval *, int, BerVarray, int ));
 LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P((
 				Operation *, struct berval *, struct berval *, int, int ));
 LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P((
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index c9e2453a88..dd91c87a1a 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -222,10 +222,10 @@ do_search(
 	rs->sr_err = frontendDB->be_search( op, rs );
 
 return_results:;
+#if 0	/* DELETE ME */
 	if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) {
 		return rs->sr_err;
 	}
-#if 0
 	if ( ( op->o_sync_slog_size != -1 ) ) {
 		return rs->sr_err;
 	}
@@ -351,6 +351,7 @@ fe_op_search( Operation *op, SlapReply *rs )
 	 * if we don't hold it.
 	 */
 
+#if 0	/* DELETE ME */
 	/* Sync control overrides manageDSAit */
 
 	if ( manageDSAit != SLAP_CONTROL_NONE ) {
@@ -362,6 +363,9 @@ fe_op_search( Operation *op, SlapReply *rs )
 	} else {
 		be_manageDSAit = manageDSAit;
 	}
+#else
+		be_manageDSAit = manageDSAit;
+#endif
 
 	op->o_bd = select_backend( &op->o_req_ndn, be_manageDSAit, 1 );
 	if ( op->o_bd == NULL ) {
diff --git a/servers/slapd/sessionlog.c b/servers/slapd/sessionlog.c
index 8bcbdcdbbe..3d21368c18 100644
--- a/servers/slapd/sessionlog.c
+++ b/servers/slapd/sessionlog.c
@@ -26,7 +26,7 @@
 #include "slap.h"
 #include "lutil_ldap.h"
 
-#if 0
+#if 0	/* DELETE ME -- needs to be reimplemented with syncprov overlay */
 int
 slap_send_session_log(
 	Operation *op,
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index eb8ad85764..f0bd6fa600 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -2129,13 +2129,8 @@ struct slap_control_ids {
 	int sc_treeDelete;
 	int sc_searchOptions;
 	int sc_subentries;
-	int sc_LDAPsync;
 };
 
-typedef struct syncrepl_state {
-	struct sync_cookie sr_state;
-	int sr_rhint;
-} syncrepl_state;
 /*
  * represents an operation pending from an ldap client
  */
@@ -2335,14 +2330,6 @@ typedef struct slap_op {
 
 #define get_pagedresults(op)			((int)(op)->o_pagedresults)
 
-#define	o_sync	o_ctrlflag[slap_cids.sc_LDAPsync]
-	/* o_sync_mode uses data bits of o_sync */
-#define	o_sync_mode	o_ctrlflag[slap_cids.sc_LDAPsync]
-
-#define SLAP_SYNC_NONE					(LDAP_SYNC_NONE<<SLAP_CONTROL_SHIFT)
-#define SLAP_SYNC_REFRESH				(LDAP_SYNC_REFRESH_ONLY<<SLAP_CONTROL_SHIFT)
-#define SLAP_SYNC_PERSIST				(LDAP_SYNC_RESERVED<<SLAP_CONTROL_SHIFT)
-#define SLAP_SYNC_REFRESH_AND_PERSIST	(LDAP_SYNC_REFRESH_AND_PERSIST<<SLAP_CONTROL_SHIFT)
 #ifdef BDB_PSEARCH
 	struct sync_cookie	o_sync_state;
 	int					o_sync_rhint;
@@ -2381,6 +2368,7 @@ typedef struct slap_op {
 	int	o_delete_glue_parent;
 
 } Operation;
+#define	OPERATION_BUFFER_SIZE	(sizeof(Operation)+sizeof(Opheader)+SLAP_MAX_CIDS*sizeof(void *))
 
 #define send_ldap_error( op, rs, err, text ) do { \
 		(rs)->sr_err = err; (rs)->sr_text = text; \
diff --git a/servers/slapd/slapacl.c b/servers/slapd/slapacl.c
index b7d1928706..6e8e5e3653 100644
--- a/servers/slapd/slapacl.c
+++ b/servers/slapd/slapacl.c
@@ -40,8 +40,8 @@ slapacl( int argc, char **argv )
 	int			rc = EXIT_SUCCESS;
 	const char		*progname = "slapacl";
 	Connection		conn = {0};
-	Operation		op = {0};
-	Opheader		ohdr = {0};
+	char opbuf[OPERATION_BUFFER_SIZE];
+	Operation		*op;
 	Entry			e = { 0 };
 	char			*attr = NULL;
 
@@ -50,10 +50,11 @@ slapacl( int argc, char **argv )
 	argv = &argv[ optind ];
 	argc -= optind;
 
-	connection_fake_init( &conn, &op, &ohdr, &conn );
+	op = (Operation *)opbuf;
+	connection_fake_init( &conn, op, &conn );
 
 	if ( !BER_BVISNULL( &authcID ) ) {
-		rc = slap_sasl_getdn( &conn, &op, &authcID, NULL,
+		rc = slap_sasl_getdn( &conn, op, &authcID, NULL,
 				&authcDN, SLAP_GETDN_AUTHCID );
 		if ( rc != LDAP_SUCCESS ) {
 			fprintf( stderr, "ID: <%s> check failed %d (%s)\n",
@@ -93,10 +94,10 @@ slapacl( int argc, char **argv )
 		goto destroy;
 	}
 
-	op.o_bd = be;
+	op->o_bd = be;
 	if ( !BER_BVISNULL( &authcDN ) ) {
-		op.o_dn = authcDN;
-		op.o_ndn = authcDN;
+		op->o_dn = authcDN;
+		op->o_ndn = authcDN;
 	}
 
 	if ( argc == 0 ) {
@@ -150,7 +151,7 @@ slapacl( int argc, char **argv )
 			break;
 		}
 
-		rc = access_allowed_mask( &op, &e, desc, &val, access,
+		rc = access_allowed_mask( op, &e, desc, &val, access,
 				NULL, &mask );
 
 		if ( accessstr ) {
diff --git a/servers/slapd/slapauth.c b/servers/slapd/slapauth.c
index 06dd27709d..73b2ceb93d 100644
--- a/servers/slapd/slapauth.c
+++ b/servers/slapd/slapauth.c
@@ -80,20 +80,21 @@ slapauth( int argc, char **argv )
 	int			rc = EXIT_SUCCESS;
 	const char		*progname = "slapauth";
 	Connection		conn = {0};
-	Operation		op = {0};
-	Opheader		ohdr = {0};
+	char			opbuf[OPERATION_BUFFER_SIZE];
+	Operation		*op;
 
 	slap_tool_init( progname, SLAPAUTH, argc, argv );
 
 	argv = &argv[ optind ];
 	argc -= optind;
 
-	connection_fake_init( &conn, &op, &ohdr, &conn );
+	op = (Operation *)opbuf;
+	connection_fake_init( &conn, op, &conn );
 
 	if ( !BER_BVISNULL( &authzID ) ) {
 		struct berval	authzdn;
 		
-		rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn,
+		rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
 				SLAP_GETDN_AUTHZID );
 		if ( rc != LDAP_SUCCESS ) {
 			fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
@@ -110,7 +111,7 @@ slapauth( int argc, char **argv )
 
 	if ( !BER_BVISNULL( &authcID ) ) {
 		if ( !BER_BVISNULL( &authzID ) || argc == 0 ) {
-			rc = do_check( &conn, &op, &authcID );
+			rc = do_check( &conn, op, &authcID );
 			goto destroy;
 		}
 
@@ -119,7 +120,7 @@ slapauth( int argc, char **argv )
 		
 			ber_str2bv( argv[ 0 ], 0, 0, &authzID );
 
-			rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn,
+			rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
 					SLAP_GETDN_AUTHZID );
 			if ( rc != LDAP_SUCCESS ) {
 				fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
@@ -134,9 +135,9 @@ slapauth( int argc, char **argv )
 
 			authzID = authzdn;
 
-			rc = do_check( &conn, &op, &authcID );
+			rc = do_check( &conn, op, &authcID );
 
-			op.o_tmpfree( authzID.bv_val, op.o_tmpmemctx );
+			op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
 			BER_BVZERO( &authzID );
 
 			if ( rc && !continuemode ) {
@@ -152,7 +153,7 @@ slapauth( int argc, char **argv )
 
 		ber_str2bv( argv[ 0 ], 0, 0, &id );
 
-		rc = do_check( &conn, &op, &id );
+		rc = do_check( &conn, op, &id );
 
 		if ( rc && !continuemode ) {
 			goto destroy;
@@ -161,7 +162,7 @@ slapauth( int argc, char **argv )
 
 destroy:;
 	if ( !BER_BVISNULL( &authzID ) ) {
-		op.o_tmpfree( authzID.bv_val, op.o_tmpmemctx );
+		op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
 	}
 	slap_tool_destroy();
 
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 31d308ef5b..3dc75b79ae 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -889,8 +889,8 @@ do_syncrepl(
 	struct re_s* rtask = arg;
 	syncinfo_t *si = ( syncinfo_t * ) rtask->arg;
 	Connection conn = {0};
-	Operation op = {0};
-	Opheader ohdr = {0};
+	char opbuf[OPERATION_BUFFER_SIZE];
+	Operation *op;
 	int rc = LDAP_SUCCESS;
 	int first = 0;
 	int dostop = 0;
@@ -919,30 +919,31 @@ do_syncrepl(
 		return NULL;
 	}
 
-	connection_fake_init( &conn, &op, &ohdr, ctx );
+	op = (Operation *)opbuf;
+	connection_fake_init( &conn, op, ctx );
 
 	/* use global malloc for now */
-	op.o_tmpmemctx = NULL;
-	op.o_tmpmfuncs = &ch_mfuncs;
+	op->o_tmpmemctx = NULL;
+	op->o_tmpmfuncs = &ch_mfuncs;
 
-	op.o_dn = si->si_updatedn;
-	op.o_ndn = si->si_updatedn;
-	op.o_managedsait = SLAP_CONTROL_NONCRITICAL;
-	op.o_bd = be = si->si_be;
+	op->o_dn = si->si_updatedn;
+	op->o_ndn = si->si_updatedn;
+	op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
+	op->o_bd = be = si->si_be;
 
 	/* Establish session, do search */
 	if ( !si->si_ld ) {
 		first = 1;
 		si->si_refreshDelete = 0;
 		si->si_refreshPresent = 0;
-		rc = do_syncrep1( &op, si );
+		rc = do_syncrep1( op, si );
 	}
 
 	/* Process results */
 	if ( rc == LDAP_SUCCESS ) {
 		ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
 
-		rc = do_syncrep2( &op, si );
+		rc = do_syncrep2( op, si );
 
 		if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
 			/* If we succeeded, enable the connection for further listening.
@@ -1293,7 +1294,7 @@ syncrepl_entry(
 	if ( rs_search.sr_err == LDAP_SUCCESS &&
 		 !BER_BVISNULL( &si->si_syncUUID_ndn ))
 	{
-#if 0
+#if 0	/* DELETE ME -- and fix this to do realy Modifies */
 		char *subseq_ptr;
 
 		if ( syncstate != LDAP_SYNC_DELETE ) {
@@ -1346,10 +1347,6 @@ syncrepl_entry(
 		op->o_req_dn = org_req_dn;
 		op->o_req_ndn = org_req_ndn;
 		op->o_delete_glue_parent = 0;
-
-#if 0
-		op->o_no_psearch = 0;
-#endif
 	}
 
 	switch ( syncstate ) {
-- 
GitLab