diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in
index a58e5421ebff0d31c8433dd205c2ac32664bc745..e305e7fc313b1aa06b46f9dfaa8815f0fb39de74 100644
--- a/servers/slapd/Makefile.in
+++ b/servers/slapd/Makefile.in
@@ -35,7 +35,7 @@ SRCS	= main.c globals.c config.c daemon.c \
 		oidm.c starttls.c index.c sets.c referral.c root_dse.c \
 		sasl.c module.c mra.c mods.c sl_malloc.c limits.c \
 		backglue.c operational.c matchedValues.c cancel.c syncrepl.c \
-		backover.c ctxcsn.c ldapsync.c sessionlog.c \
+		backover.c ctxcsn.c ldapsync.c sessionlog.c frontend.c \
 		slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
 		slappasswd.c slaptest.c slapauth.c slapacl.c \
 		$(@PLAT@_SRCS)
@@ -52,7 +52,7 @@ OBJS	= main.o globals.o config.o daemon.o \
 		oidm.o starttls.o index.o sets.o referral.o root_dse.o \
 		sasl.o module.o mra.o mods.o sl_malloc.o limits.o \
 		backglue.o operational.o matchedValues.o cancel.o syncrepl.o \
-		backover.o ctxcsn.o ldapsync.o sessionlog.o \
+		backover.o ctxcsn.o ldapsync.o sessionlog.o frontend.o \
 		slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
 		slappasswd.o slaptest.o slapauth.o slapacl.o \
 		$(@PLAT@_OBJS)
diff --git a/servers/slapd/abandon.c b/servers/slapd/abandon.c
index d6f8181933c88df7fa1c93fd5ef7657e93a25fef..559bcaaa5177a272dd4c898ba7735afc9b79196f 100644
--- a/servers/slapd/abandon.c
+++ b/servers/slapd/abandon.c
@@ -112,6 +112,12 @@ do_abandon( Operation *op, SlapReply *rs )
 
 done:
 	op->orn_msgid = id;
+
+	if ( frontendDB->be_abandon ) {
+		op->o_bd = frontendDB;
+		frontendDB->be_abandon( op, rs );
+	}
+
 	for ( i = 0; i < nbackends; i++ ) {
 		op->o_bd = &backends[i];
 		if( op->o_bd->be_abandon ) op->o_bd->be_abandon( op, rs );
@@ -129,3 +135,4 @@ done:
 #endif
 	return LDAP_SUCCESS;
 }
+
diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 7000494292125d3f861821d3263f37476e24c855..d0a2976190c392f0e16a8badaa8e47035f93b6e3 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -224,7 +224,7 @@ access_allowed_mask(
 		/*
 		 * FIXME: experimental; use first backend rules
 		 * iff there is no global_acl (ITS#3100) */
-		if ( global_acl == NULL ) 
+		if ( frontendDB->be_acl == NULL ) 
 #endif
 		{
 			op->o_bd = be;
@@ -312,20 +312,20 @@ access_allowed_mask(
 #ifdef notdef
 	/* be is always non-NULL */
 	/* use global default access if no global acls */
-	} else if ( be == NULL && global_acl == NULL ) {
+	} else if ( be == NULL && frontendDB->be_acl == NULL ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( ACL, DETAIL1, 
 			"access_allowed: global default %s access %s to \"%s\"\n",
 		    access2str( access ),
-		    global_default_access >= access ? "granted" : "denied", 
+		    frontendDB->be_dfltaccess >= access ? "granted" : "denied", 
 			op->o_dn.bv_val );
 #else
 		Debug( LDAP_DEBUG_ACL,
 			"=> access_allowed: global default %s access %s to \"%s\"\n",
 			access2str( access ),
-			global_default_access >= access ? "granted" : "denied", op->o_dn.bv_val );
+			frontendDB->be_dfltaccess >= access ? "granted" : "denied", op->o_dn.bv_val );
 #endif
-		ret = global_default_access >= access;
+		ret = frontendDB->be_dfltaccess >= access;
 
 		if ( maskp ) {
 			int	i;
@@ -496,7 +496,7 @@ acl_get(
 
 	if( a == NULL ) {
 		if( op->o_bd == NULL ) {
-			a = global_acl;
+			a = frontendDB->be_acl;
 		} else {
 			a = op->o_bd->be_acl;
 		}
diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c
index b8c970d4d0d66e589a1f844744791132787d2012..c039c6e25a5a8eec7691268f5b91e775bba0e66a 100644
--- a/servers/slapd/aclparse.c
+++ b/servers/slapd/aclparse.c
@@ -1573,7 +1573,7 @@ parse_acl(
 #endif /* LDAP_DEVEL */
 			acl_append( &be->be_acl, a );
 		} else {
-			acl_append( &global_acl, a );
+			acl_append( &frontendDB->be_acl, a );
 		}
 	}
 }
diff --git a/servers/slapd/add.c b/servers/slapd/add.c
index db2b0743ba93db6ac0d8ed50b2fc490472477be6..0ed59d33167b7192566a1780cb676179ae018761 100644
--- a/servers/slapd/add.c
+++ b/servers/slapd/add.c
@@ -47,14 +47,13 @@ do_add( Operation *op, SlapReply *rs )
 {
 	BerElement	*ber = op->o_ber;
 	char		*last;
-	struct berval dn = BER_BVNULL;
+	struct berval	dn = BER_BVNULL;
 	ber_len_t	len;
 	ber_tag_t	tag;
 	Entry		*e;
 	Modifications	*modlist = NULL;
 	Modifications	**modtail = &modlist;
 	Modifications	tmp;
-	int	manageDSAit;
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", op->o_connid,0,0 );
@@ -197,12 +196,45 @@ do_add( Operation *op, SlapReply *rs )
 			"root DSE already exists" );
 		goto done;
 
-	} else if ( bvmatch( &e->e_nname, &global_schemandn ) ) {
+	} else if ( bvmatch( &e->e_nname, &frontendDB->be_schemandn ) ) {
 		send_ldap_error( op, rs, LDAP_ALREADY_EXISTS,
 			"subschema subentry already exists" );
 		goto done;
 	}
 
+	/* temporary; remove if not invoking backend function */
+	op->ora_e = e;
+	op->ora_modlist = modlist;
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_add( op, rs );
+	if ( rs->sr_err == 0 ) {
+		e = NULL;
+	}
+
+done:;
+	slap_graduate_commit_csn( op );
+
+	if( modlist != NULL ) {
+		slap_mods_free( modlist );
+	}
+	if( e != NULL ) {
+		entry_free( e );
+	}
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+
+	return rs->sr_err;
+}
+
+int
+fe_op_add( Operation *op, SlapReply *rs )
+{
+	int		manageDSAit;
+	Entry		*e = op->ora_e;
+	Modifications	*modlist = op->ora_modlist;
+	Modifications	**modtail = &modlist;
+
 	manageDSAit = get_manageDSAit( op );
 
 	/*
@@ -241,7 +273,7 @@ do_add( Operation *op, SlapReply *rs )
 	}
 
 #ifdef LDAP_SLAPI
-	if ( op->o_pb ) init_add_pblock( op, &dn, e, manageDSAit );
+	if ( op->o_pb ) init_add_pblock( op, &op->o_req_dn, e, manageDSAit );
 #endif /* LDAP_SLAPI */
 
 	/*
@@ -382,18 +414,7 @@ do_add( Operation *op, SlapReply *rs )
 	if ( op->o_pb ) call_add_postop_plugins( op );
 #endif /* LDAP_SLAPI */
 
-done:
-	slap_graduate_commit_csn( op );
-
-	if( modlist != NULL ) {
-		slap_mods_free( modlist );
-	}
-	if( e != NULL ) {
-		entry_free( e );
-	}
-	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
-	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-
+done:;
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c
index 1e3658b555c75e1e8813a7de2f0a032d4de68bac..f70e937dc34b7a0d8bdef5fca56b1fd42a162790 100644
--- a/servers/slapd/back-monitor/database.c
+++ b/servers/slapd/back-monitor/database.c
@@ -126,8 +126,8 @@ monitor_subsys_database_init(
 		return( -1 );
 	}
 
-	(void)init_readOnly( mi, e_database, global_restrictops );
-	(void)init_restrictedOperation( mi, e_database, global_restrictops );
+	(void)init_readOnly( mi, e_database, frontendDB->be_restrictops );
+	(void)init_restrictedOperation( mi, e_database, frontendDB->be_restrictops );
 
 	e_tmp = NULL;
 	for ( i = nBackendDB; i--; ) {
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 3524370b4e473b993a6d71685b433654a2b7e712..a5933e7cb17b99bc4e1ed26d4f93593187b738f3 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -357,6 +357,23 @@ int backend_startup(Backend *be)
 		return backend_startup_one( be );
 	}
 
+	/* open frontend, if required */
+	if ( frontendDB->bd_info->bi_db_open ) {
+		rc = frontendDB->bd_info->bi_db_open( frontendDB );
+		if ( rc != 0 ) {
+#ifdef NEW_LOGGING
+			LDAP_LOG( BACKEND, CRIT, 
+				"backend_startup: bi_db_open(frontend) failed! (%d)\n",
+				rc, 0, 0 );
+#else
+			Debug( LDAP_DEBUG_ANY,
+				"backend_startup: bi_db_open(frontend) failed! (%d)\n",
+				rc, 0, 0 );
+#endif
+			return rc;
+		}
+	}
+
 	/* open each backend type */
 	for( i = 0; i < nBackendInfo; i++ ) {
 		if( backendInfo[i].bi_nDB == 0) {
@@ -401,7 +418,7 @@ int backend_startup(Backend *be)
 #endif
 		}
 		/* append global access controls */
-		acl_append( &backendDB[i].be_acl, global_acl );
+		acl_append( &backendDB[i].be_acl, frontendDB->be_acl );
 
 		rc = backend_startup_one( &backendDB[i] );
 
@@ -485,11 +502,11 @@ int backend_shutdown( Backend *be )
 		if(rc != 0) {
 #ifdef NEW_LOGGING
 			LDAP_LOG( BACKEND, NOTICE, 
-				"backend_shutdown: bi_close %s failed!\n",
+				"backend_shutdown: bi_db_close %s failed!\n",
 				backendDB[i].be_type, 0, 0 );
 #else
 			Debug( LDAP_DEBUG_ANY,
-				"backend_close: bi_close %s failed!\n",
+				"backend_close: bi_db_close %s failed!\n",
 				backendDB[i].be_type, 0, 0 );
 #endif
 		}
@@ -508,6 +525,22 @@ int backend_shutdown( Backend *be )
 		}
 	}
 
+	/* close frontend, if required */
+	if ( frontendDB->bd_info->bi_db_close ) {
+		rc = frontendDB->bd_info->bi_db_close ( frontendDB );
+		if ( rc != 0 ) {
+#ifdef NEW_LOGGING
+			LDAP_LOG( BACKEND, CRIT, 
+				"backend_startup: bi_db_close(frontend) failed! (%d)\n",
+				rc, 0, 0 );
+#else
+			Debug( LDAP_DEBUG_ANY,
+				"backend_startup: bi_db_close(frontend) failed! (%d)\n",
+				rc, 0, 0 );
+#endif
+		}
+	}
+
 	return 0;
 }
 
@@ -529,7 +562,7 @@ int backend_destroy(void)
 		if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val );
 		if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val );
 		if ( bd->be_context_csn.bv_val ) free( bd->be_context_csn.bv_val );
-		acl_destroy( bd->be_acl, global_acl );
+		acl_destroy( bd->be_acl, frontendDB->be_acl );
 	}
 	free( backendDB );
 
@@ -550,6 +583,18 @@ int backend_destroy(void)
 	nBackendInfo = 0;
 	backendInfo = NULL;
 
+	/* destroy frontend database */
+	bd = frontendDB;
+	if ( bd->bd_info->bi_db_destroy ) {
+		bd->bd_info->bi_db_destroy( bd );
+	}
+	ber_bvarray_free( bd->be_suffix );
+	ber_bvarray_free( bd->be_nsuffix );
+	if ( bd->be_rootdn.bv_val ) free( bd->be_rootdn.bv_val );
+	if ( bd->be_rootndn.bv_val ) free( bd->be_rootndn.bv_val );
+	if ( bd->be_rootpw.bv_val ) free( bd->be_rootpw.bv_val );
+	acl_destroy( bd->be_acl, frontendDB->be_acl );
+
 	return 0;
 }
 
@@ -590,12 +635,12 @@ backend_db_init(
 	be = &backends[nbackends++];
 
 	be->bd_info = bi;
-	be->be_def_limit = deflimit;
-	be->be_dfltaccess = global_default_access;
+	be->be_def_limit = frontendDB->be_def_limit;
+	be->be_dfltaccess = frontendDB->be_dfltaccess;
 
-	be->be_restrictops = global_restrictops;
-	be->be_requires = global_requires;
-	be->be_ssf_set = global_ssf_set;
+	be->be_restrictops = frontendDB->be_restrictops;
+	be->be_requires = frontendDB->be_requires;
+	be->be_ssf_set = frontendDB->be_ssf_set;
 
 	be->be_context_csn.bv_len = 0;
 	be->be_context_csn.bv_val = NULL;
@@ -631,6 +676,10 @@ be_db_close( void )
 			(*backends[i].bd_info->bi_db_close)( &backends[i] );
 		}
 	}
+
+	if ( frontendDB->bd_info->bi_db_close ) {
+		(*frontendDB->bd_info->bi_db_close)( frontendDB );
+	}
 }
 
 Backend *
@@ -949,9 +998,9 @@ backend_check_restrictions(
 		ssf = &op->o_bd->be_ssf_set;
 
 	} else {
-		restrictops = global_restrictops;
-		requires = global_requires;
-		ssf = &global_ssf_set;
+		restrictops = frontendDB->be_restrictops;
+		requires = frontendDB->be_requires;
+		ssf = &frontendDB->be_ssf_set;
 	}
 
 	switch( op->o_tag ) {
diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c
index 24ce7de52cb76ed894450cf512885007b8935044..7fcf4b498613fc72d4fbdc6e8f46d6b28d61565d 100644
--- a/servers/slapd/bind.c
+++ b/servers/slapd/bind.c
@@ -137,8 +137,7 @@ do_bind(
 				tag = ber_scanf( ber, "m", &op->orb_cred );
 			} else {
 				tag = LDAP_TAG_LDAPCRED;
-				op->orb_cred.bv_val = NULL;
-				op->orb_cred.bv_len = 0;
+				BER_BVZERO( &op->orb_cred );
 			}
 
 			if ( tag != LBER_ERROR ) {
@@ -238,6 +237,38 @@ do_bind(
 	op->o_conn->c_protocol = version;
 	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
+	op->orb_tmp_mech = mech;
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_bind( op, rs );
+
+cleanup:
+	if ( rs->sr_err == LDAP_SUCCESS ) {
+		if ( op->orb_method != LDAP_AUTH_SASL ) {
+			ber_dupbv( &op->o_conn->c_authmech, &mech );
+		}
+		op->o_conn->c_authtype = op->orb_method;
+	}
+
+	op->o_conn->c_sasl_bindop = NULL;
+
+	if( op->o_req_dn.bv_val != NULL ) {
+		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
+		BER_BVZERO( &op->o_req_dn );
+	}
+	if( op->o_req_ndn.bv_val != NULL ) {
+		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+		BER_BVZERO( &op->o_req_ndn );
+	}
+
+	return rs->sr_err;
+}
+
+int
+fe_op_bind( Operation *op, SlapReply *rs )
+{
+	struct berval	mech = op->orb_tmp_mech;
+
 	/* check for inappropriate controls */
 	if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
 		send_ldap_error( op, rs,
@@ -250,14 +281,14 @@ do_bind(
 	op->o_conn->c_sasl_bindop = op;
 
 	if ( op->orb_method == LDAP_AUTH_SASL ) {
-		if ( version < LDAP_VERSION3 ) {
+		if ( op->o_protocol < LDAP_VERSION3 ) {
 #ifdef NEW_LOGGING
 			LDAP_LOG( OPERATION, INFO, 
 				"do_bind: conn %d  sasl with LDAPv%ld\n",
-				op->o_connid, (unsigned long)version , 0 );
+				op->o_connid, (unsigned long)op->o_protocol, 0 );
 #else
 			Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
-				(unsigned long) version, 0, 0 );
+				(unsigned long)op->o_protocol, 0, 0 );
 #endif
 			send_ldap_discon( op, rs,
 				LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
@@ -350,8 +381,7 @@ do_bind(
 		} else {
 			if ( op->o_conn->c_sasl_bind_mech.bv_val ) {
 				free( op->o_conn->c_sasl_bind_mech.bv_val );
-				op->o_conn->c_sasl_bind_mech.bv_val = NULL;
-				op->o_conn->c_sasl_bind_mech.bv_len = 0;
+				BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
 			}
 			op->o_conn->c_sasl_bind_in_progress = 0;
 		}
@@ -367,7 +397,7 @@ do_bind(
 		 */
 		if ( pb ) {
 			slapi_int_pblock_set_operation( pb, op );
-			slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+			slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)op->o_req_dn.bv_val );
 			slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)op->orb_method );
 			slapi_pblock_set( pb,
 				SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred );
@@ -387,8 +417,7 @@ do_bind(
 
 		if ( op->o_conn->c_sasl_bind_mech.bv_val != NULL ) {
 			free(op->o_conn->c_sasl_bind_mech.bv_val);
-			op->o_conn->c_sasl_bind_mech.bv_val = NULL;
-			op->o_conn->c_sasl_bind_mech.bv_len = 0;
+			BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
 		}
 		op->o_conn->c_sasl_bind_in_progress = 0;
 
@@ -433,10 +462,10 @@ do_bind(
 #ifdef NEW_LOGGING
 			LDAP_LOG( OPERATION, DETAIL1, 
 				"do_bind: conn %d  v%d anonymous bind\n",
-				op->o_connid, version , 0 );
+				op->o_connid, op->o_protocol, 0 );
 #else
 			Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
-				version, 0, 0 );
+				op->o_protocol, 0, 0 );
 #endif
 			goto cleanup;
 
@@ -449,11 +478,11 @@ do_bind(
 #ifdef NEW_LOGGING
 			LDAP_LOG( OPERATION, INFO, 
 				"do_bind: conn %d  v%d simple bind(%s) disallowed\n",
-				op->o_connid, version, op->o_req_ndn.bv_val );
+				op->o_connid, op->o_protocol, op->o_req_ndn.bv_val );
 #else
 			Debug( LDAP_DEBUG_TRACE,
 				"do_bind: v%d simple bind(%s) disallowed\n",
-				version, op->o_req_ndn.bv_val, 0 );
+				op->o_protocol, op->o_req_ndn.bv_val, 0 );
 #endif
 			goto cleanup;
 		}
@@ -470,11 +499,11 @@ do_bind(
 #ifdef NEW_LOGGING
 			LDAP_LOG( OPERATION, DETAIL1, 
 				"do_bind: conn %d  v%d Kerberos V4 (step 1) bind refused\n",
-				op->o_connid, version , 0 );
+				op->o_connid, op->o_protocol, 0 );
 #else
 			Debug( LDAP_DEBUG_TRACE,
 				"do_bind: v%d Kerberos V4 (step 1) bind refused\n",
-				version, 0, 0 );
+				op->o_protocol, 0, 0 );
 #endif
 			goto cleanup;
 		}
@@ -488,11 +517,11 @@ do_bind(
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, DETAIL1, 
 			"do_bind: conn %d  v%d Kerberos V4 (step 2) bind refused\n",
-			op->o_connid, version , 0 );
+			op->o_connid, op->o_protocol, 0 );
 #else
 		Debug( LDAP_DEBUG_TRACE,
 			"do_bind: v%d Kerberos V4 (step 2) bind refused\n",
-			version, 0, 0 );
+			op->o_protocol, 0, 0 );
 #endif
 		goto cleanup;
 #endif
@@ -505,11 +534,11 @@ do_bind(
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, INFO, 
 			"do_bind: conn %ld  v%d unknown authentication method (%ld)\n",
-			op->o_connid, version, op->orb_method );
+			op->o_connid, op->o_protocol, op->orb_method );
 #else
 		Debug( LDAP_DEBUG_TRACE,
 			"do_bind: v%d unknown authentication method (%ld)\n",
-			version, op->orb_method, 0 );
+			op->o_protocol, op->orb_method, 0 );
 #endif
 		goto cleanup;
 	}
@@ -550,7 +579,7 @@ do_bind(
 	if ( pb ) {
 		int rc;
 		slapi_int_pblock_set_operation( pb, op );
-		slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+		slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)op->o_req_dn.bv_val );
 		slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)op->orb_method );
 		slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred );
 		slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
@@ -588,13 +617,12 @@ do_bind(
 				rs->sr_err = LDAP_OTHER;
 			}
 
-			op->orb_edn.bv_val = NULL;
-			op->orb_edn.bv_len = 0;
+			BER_BVZERO( &op->orb_edn );
 
 			if ( rs->sr_err == LDAP_SUCCESS ) {
 				slapi_pblock_get( pb, SLAPI_CONN_DN,
 					(void *)&op->orb_edn.bv_val );
-				if ( op->orb_edn.bv_val == NULL ) {
+				if ( BER_BVISNULL( &op->orb_edn ) ) {
 					if ( rc == 1 ) {
 						/* No plugins were called; continue. */
 						break;
@@ -608,11 +636,9 @@ do_bind(
 				ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn);
 				ber_dupbv(&op->o_conn->c_ndn, &op->o_req_ndn);
 				op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
-				op->o_req_dn.bv_val = NULL;
-				op->o_req_dn.bv_len = 0;
+				BER_BVZERO( &op->o_req_dn );
 				op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-				op->o_req_ndn.bv_val = NULL;
-				op->o_req_ndn.bv_len = 0;
+				BER_BVZERO( &op->o_req_ndn );
 				if ( op->o_conn->c_dn.bv_len != 0 ) {
 					ber_len_t max = sockbuf_max_incoming_auth;
 					ber_sockbuf_ctrl( op->o_conn->c_sb,
@@ -667,11 +693,11 @@ do_bind(
 #ifdef NEW_LOGGING
 			LDAP_LOG( OPERATION, DETAIL1, 
 				"do_bind: v%d bind: \"%s\" to \"%s\" \n",
-				version, op->o_conn->c_dn.bv_val, op->o_conn->c_dn.bv_val );
+				op->o_protocol, op->o_conn->c_dn.bv_val, op->o_conn->c_dn.bv_val );
 #else
 			Debug( LDAP_DEBUG_TRACE,
 				"do_bind: v%d bind: \"%s\" to \"%s\"\n",
-				version, dn.bv_val, op->o_conn->c_dn.bv_val );
+				op->o_protocol, op->o_req_dn.bv_val, op->o_conn->c_dn.bv_val );
 #endif
 
 			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
@@ -704,24 +730,7 @@ do_bind(
 	}
 #endif /* LDAP_SLAPI */
 
-cleanup:
-	if ( rs->sr_err == LDAP_SUCCESS ) {
-		if ( op->orb_method != LDAP_AUTH_SASL ) {
-			ber_dupbv( &op->o_conn->c_authmech, &mech );
-		}
-		op->o_conn->c_authtype = op->orb_method;
-	}
-
-	op->o_conn->c_sasl_bindop = NULL;
-
-	if( op->o_req_dn.bv_val != NULL ) {
-		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
-		op->o_req_dn.bv_val = NULL;
-	}
-	if( op->o_req_ndn.bv_val != NULL ) {
-		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-		op->o_req_ndn.bv_val = NULL;
-	}
-
+cleanup:;
 	return rs->sr_err;
 }
+
diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c
index a291cfc5e13e5dae3d7d8dbb5ab2050cf9c0698c..6680c43e4885ba00170d2383f1638cf9abf02991 100644
--- a/servers/slapd/compare.c
+++ b/servers/slapd/compare.c
@@ -45,12 +45,10 @@ do_compare(
     Operation	*op,
     SlapReply	*rs )
 {
-	Entry *entry = NULL;
 	struct berval dn = BER_BVNULL;
 	struct berval desc = BER_BVNULL;
 	struct berval value = BER_BVNULL;
 	AttributeAssertion ava = { NULL, BER_BVNULL };
-	int manageDSAit;
 
 	ava.aa_desc = NULL;
 
@@ -144,6 +142,28 @@ do_compare(
 		goto cleanup;
 	}
 
+	op->orc_ava = &ava;
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_compare( op, rs );
+
+cleanup:;
+	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 ( ava.aa_value.bv_val ) {
+		op->o_tmpfree( ava.aa_value.bv_val, op->o_tmpmemctx );
+	}
+
+	return rs->sr_err;
+}
+
+int
+fe_op_compare( Operation *op, SlapReply *rs )
+{
+	Entry *entry = NULL;
+	int manageDSAit;
+	AttributeAssertion ava = *op->orc_ava;
+
 	if( strcasecmp( op->o_req_ndn.bv_val, LDAP_ROOT_DSE ) == 0 ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, ARGS, 
@@ -173,7 +193,7 @@ do_compare(
 			goto cleanup;
 		}
 
-	} else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) {
+	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, ARGS, 
 			"do_compare: dn (%s) attr(%s) value (%s)\n",
@@ -270,10 +290,10 @@ do_compare(
 #define	pb	op->o_pb
 	if ( pb ) {
 		slapi_int_pblock_set_operation( pb, op );
-		slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)dn.bv_val );
+		slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)op->o_req_dn.bv_val );
 		slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
-		slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val );
-		slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value );
+		slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)ava.aa_desc->ad_cname.bv_val );
+		slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&ava.aa_value );
 
 		rs->sr_err = slapi_int_call_plugins( op->o_bd,
 			SLAPI_PLUGIN_PRE_COMPARE_FN, pb );
@@ -323,12 +343,7 @@ do_compare(
 	}
 #endif /* defined( LDAP_SLAPI ) */
 
-cleanup:
-	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 ( ava.aa_value.bv_val ) {
-		op->o_tmpfree( ava.aa_value.bv_val, op->o_tmpmemctx );
-	}
+cleanup:;
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index cf0508ff409c58e394fa139bbb5c0d3899439049..71fb0dcb486be4b107ff26d58f5d32c417eab7bb 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -46,25 +46,8 @@
 /*
  * defaults for various global variables
  */
-struct slap_limits_set deflimit = {
-	SLAPD_DEFAULT_TIMELIMIT,	/* backward compatible limits */
-	0,
-
-	SLAPD_DEFAULT_SIZELIMIT,	/* backward compatible limits */
-	0,
-	-1,				/* no limit on unchecked size */
-	0,				/* page limit */
-	0,				/* hide number of entries left */
-	0				/* number of total entries returned by pagedResults equal to hard limit */
-};
-
-AccessControl	*global_acl = NULL;
-slap_access_t		global_default_access = ACL_READ;
-slap_mask_t		global_restrictops = 0;
 slap_mask_t		global_allows = 0;
 slap_mask_t		global_disallows = 0;
-slap_mask_t		global_requires = 0;
-slap_ssf_set_t	global_ssf_set;
 char		*replogfile;
 int		global_gentlehup = 0;
 int		global_idletimeout = 0;
@@ -77,8 +60,6 @@ char	**cargv;
 struct berval default_search_base = BER_BVNULL;
 struct berval default_search_nbase = BER_BVNULL;
 unsigned		num_subordinates = 0;
-struct berval global_schemadn = BER_BVNULL;
-struct berval global_schemandn = BER_BVNULL;
 
 ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
 ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
@@ -747,8 +728,8 @@ read_config( const char *fname, int depth )
 				rc = dnPrettyNormal( NULL, &dn, &be->be_schemadn,
 					&be->be_schemandn, NULL );
 			} else {
-				rc = dnPrettyNormal( NULL, &dn, &global_schemadn,
-					&global_schemandn, NULL );
+				rc = dnPrettyNormal( NULL, &dn, &frontendDB->be_schemadn,
+					&frontendDB->be_schemandn, NULL );
 			}
 			if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -818,7 +799,7 @@ read_config( const char *fname, int depth )
 			}
 
 			if ( be == NULL ) {
-				lim = &deflimit;
+				lim = &frontendDB->be_def_limit;
 			} else {
 				lim = &be->be_def_limit;
 			}
@@ -896,7 +877,7 @@ read_config( const char *fname, int depth )
 			}
 			
 			if ( be == NULL ) {
-				lim = &deflimit;
+				lim = &frontendDB->be_def_limit;
 			} else {
 				lim = &be->be_def_limit;
 			}
@@ -995,16 +976,20 @@ read_config( const char *fname, int depth )
 		/* add an overlay to this backend */
 		} else if ( strcasecmp( cargv[0], "overlay" ) == 0 ) {
 			if ( be == NULL ) {
+				if ( cargv[1][0] == '-' && overlay_config( frontendDB, &cargv[1][1] ) ) {
+					/* log error */
 #ifdef NEW_LOGGING
-				LDAP_LOG( CONFIG, INFO, "%s: line %d: "
-					"overlay keyword must appear inside a database "
-					"definition.\n", fname, lineno, 0 );
+					LDAP_LOG( CONFIG, INFO, "%s: line %d: "
+						"(optional) global overlay \"%s\" configuration "
+						"failed (ignored)\n", fname, lineno, &cargv[1][1] );
 #else
-				Debug( LDAP_DEBUG_ANY, "%s: line %d: overlay keyword "
-					"must appear inside a database definition.\n",
-				    fname, lineno, 0 );
+					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+						"(optional) global overlay \"%s\" configuration "
+						"failed (ignored)\n", fname, lineno, &cargv[1][1] );
 #endif
-				return 1;
+				} else if ( overlay_config( frontendDB, cargv[1] ) ) {
+					return 1;
+				}
 
 			} else {
 				if ( cargv[1][0] == '-' && overlay_config( be, &cargv[1][1] ) ) {
@@ -1326,10 +1311,11 @@ read_config( const char *fname, int depth )
 			}
 			if ( be == NULL ) {
 				if ( strcasecmp( cargv[1], "on" ) == 0 ) {
-					global_restrictops |= SLAP_RESTRICT_OP_WRITES;
+					frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
 				} else {
-					global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
+					frontendDB->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
 				}
+
 			} else {
 				if ( strcasecmp( cargv[1], "on" ) == 0 ) {
 					be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
@@ -1442,7 +1428,7 @@ restrict_unknown:;
 			}
 
 			if ( be == NULL ) {
-				global_restrictops |= restrict;
+				frontendDB->be_restrictops |= restrict;
 
 			} else {
 				be->be_restrictops |= restrict;
@@ -1637,7 +1623,7 @@ restrict_unknown:;
 			}
 
 			if ( be == NULL ) {
-				global_requires = requires;
+				frontendDB->be_requires = requires;
 			} else {
 				be->be_requires = requires;
 			}
@@ -1661,7 +1647,7 @@ restrict_unknown:;
 			}
 
 			if ( be == NULL ) {
-				set = &global_ssf_set;
+				set = &frontendDB->be_ssf_set;
 			} else {
 				set = &be->be_ssf_set;
 			}
@@ -2810,17 +2796,30 @@ restrict_unknown:;
 				}
 
 			} else {
+				if ( frontendDB->be_config ) {
+					rc = (*frontendDB->be_config)( frontendDB, fname, lineno, cargc, cargv );
+
+					switch ( rc ) {
+					case 0:
+						break;
+
+					case SLAP_CONF_UNKNOWN:
 #ifdef NEW_LOGGING
-				LDAP_LOG( CONFIG, INFO, 
-					"%s: line %d: unknown directive \"%s\" outside backend "
-					"info and database definitions (ignored).\n",
-					fname, lineno, cargv[0] );
+						LDAP_LOG( CONFIG, INFO, 
+							"%s: line %d: unknown directive \"%s\" inside "
+							"global database definition (ignored).\n",
+							fname, lineno, cargv[0] );
 #else
-				Debug( LDAP_DEBUG_ANY,
-"%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
-				    fname, lineno, cargv[0] );
+						Debug( LDAP_DEBUG_ANY,
+"%s: line %d: unknown directive \"%s\" inside global database definition (ignored)\n",
+							fname, lineno, cargv[0] );
 #endif
+						break;
 
+					default:
+						return 1;
+					}
+				}
 			}
 		}
 		free( saveline );
@@ -2829,10 +2828,10 @@ restrict_unknown:;
 
 	if ( depth == 0 ) ch_free( cargv );
 
-	if ( !global_schemadn.bv_val ) {
+	if ( BER_BVISNULL( &frontendDB->be_schemadn ) ) {
 		ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1,
-			&global_schemadn );
-		dnNormalize( 0, NULL, NULL, &global_schemadn, &global_schemandn, NULL );
+			&frontendDB->be_schemadn );
+		dnNormalize( 0, NULL, NULL, &frontendDB->be_schemadn, &frontendDB->be_schemandn, NULL );
 	}
 
 	if ( load_ucdata( NULL ) < 0 ) return 1;
@@ -3059,8 +3058,8 @@ void
 config_destroy( )
 {
 	ucdata_unload( UCDATA_ALL );
-	free( global_schemandn.bv_val );
-	free( global_schemadn.bv_val );
+	free( frontendDB->be_schemandn.bv_val );
+	free( frontendDB->be_schemadn.bv_val );
 	free( line );
 	if ( slapd_args_file )
 		free ( slapd_args_file );
@@ -3068,7 +3067,7 @@ config_destroy( )
 		free ( slapd_pid_file );
 	if ( default_passwd_hash )
 		ldap_charray_free( default_passwd_hash );
-	acl_destroy( global_acl, NULL );
+	acl_destroy( frontendDB->be_acl, NULL );
 }
 
 static int
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 3283e7a34061d91d32bf345f22d6c1a3318de7ea..56253ce6f2004b1c37fae51ce97b4fa5fca095a0 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -463,24 +463,18 @@ long connection_init(
 		c->c_send_ldap_intermediate = slap_send_ldap_intermediate;
 #endif
 
-		c->c_authmech.bv_val = NULL;
-		c->c_authmech.bv_len = 0;
-		c->c_dn.bv_val = NULL;
-		c->c_dn.bv_len = 0;
-		c->c_ndn.bv_val = NULL;
-		c->c_ndn.bv_len = 0;
+		BER_BVZERO( &c->c_authmech );
+		BER_BVZERO( &c->c_dn );
+		BER_BVZERO( &c->c_ndn );
 
 		c->c_listener = NULL;
-		c->c_peer_domain.bv_val = NULL;
-		c->c_peer_domain.bv_len = 0;
-		c->c_peer_name.bv_val = NULL;
-		c->c_peer_name.bv_len = 0;
+		BER_BVZERO( &c->c_peer_domain );
+		BER_BVZERO( &c->c_peer_name );
 
 		LDAP_STAILQ_INIT(&c->c_ops);
 		LDAP_STAILQ_INIT(&c->c_pending_ops);
 
-		c->c_sasl_bind_mech.bv_val = NULL;
-		c->c_sasl_bind_mech.bv_len = 0;
+		BER_BVZERO( &c->c_sasl_bind_mech );
 		c->c_sasl_done = 0;
 		c->c_sasl_authctx = NULL;
 		c->c_sasl_sockctx = NULL;
@@ -513,15 +507,15 @@ long connection_init(
 	ldap_pvt_thread_mutex_lock( &c->c_mutex );
 
 	assert( c->c_struct_state == SLAP_C_UNUSED );
-	assert( c->c_authmech.bv_val == NULL );
-	assert( c->c_dn.bv_val == NULL );
-	assert( c->c_ndn.bv_val == NULL );
+	assert( BER_BVISNULL( &c->c_authmech ) );
+	assert( BER_BVISNULL( &c->c_dn ) );
+	assert( BER_BVISNULL( &c->c_ndn ) );
 	assert( c->c_listener == NULL );
-	assert( c->c_peer_domain.bv_val == NULL );
-	assert( c->c_peer_name.bv_val == NULL );
+	assert( BER_BVISNULL( &c->c_peer_domain ) );
+	assert( BER_BVISNULL( &c->c_peer_name ) );
 	assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
 	assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
-	assert( c->c_sasl_bind_mech.bv_val == NULL );
+	assert( BER_BVISNULL( &c->c_sasl_bind_mech ) );
 	assert( c->c_sasl_done == 0 );
 	assert( c->c_sasl_authctx == NULL );
 	assert( c->c_sasl_sockctx == NULL );
@@ -648,20 +642,17 @@ void connection2anonymous( Connection *c )
 
 	if(c->c_authmech.bv_val != NULL ) {
 		free(c->c_authmech.bv_val);
-		c->c_authmech.bv_val = NULL;
 	}
-	c->c_authmech.bv_len = 0;
+	BER_BVZERO( &c->c_authmech );
 
 	if(c->c_dn.bv_val != NULL) {
 		free(c->c_dn.bv_val);
-		c->c_dn.bv_val = NULL;
 	}
-	c->c_dn.bv_len = 0;
+	BER_BVZERO( &c->c_dn );
 	if(c->c_ndn.bv_val != NULL) {
 		free(c->c_ndn.bv_val);
-		c->c_ndn.bv_val = NULL;
 	}
-	c->c_ndn.bv_len = 0;
+	BER_BVZERO( &c->c_ndn );
 
 	c->c_authz_backend = NULL;
 }
@@ -695,21 +686,18 @@ connection_destroy( Connection *c )
 
 	if(c->c_peer_domain.bv_val != NULL) {
 		free(c->c_peer_domain.bv_val);
-		c->c_peer_domain.bv_val = NULL;
 	}
-	c->c_peer_domain.bv_len = 0;
+	BER_BVZERO( &c->c_peer_domain );
 	if(c->c_peer_name.bv_val != NULL) {
 		free(c->c_peer_name.bv_val);
-		c->c_peer_name.bv_val = NULL;
 	}
-	c->c_peer_name.bv_len = 0;
+	BER_BVZERO( &c->c_peer_name );
 
 	c->c_sasl_bind_in_progress = 0;
 	if(c->c_sasl_bind_mech.bv_val != NULL) {
 		free(c->c_sasl_bind_mech.bv_val);
-		c->c_sasl_bind_mech.bv_val = NULL;
 	}
-	c->c_sasl_bind_mech.bv_len = 0;
+	BER_BVZERO( &c->c_sasl_bind_mech );
 
 	slap_sasl_close( c );
 
diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
index 5b8deba052dcdef663d6ad4388195352e1d144a1..cfa9873631974fa9a173abfb5735322991d9b6a2 100644
--- a/servers/slapd/daemon.c
+++ b/servers/slapd/daemon.c
@@ -1305,7 +1305,7 @@ slapd_daemon_task(
 			if( slapd_gentle_shutdown == 1 ) {
 				Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
 				close_listeners( 1 );
-				global_restrictops |= SLAP_RESTRICT_OP_WRITES;
+				frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
 				slapd_gentle_shutdown = 2;
 			}
 
diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c
index 7bc2f42ed7423da70bd17eb2a79579432d0f053c..a73f5b5934fc3b61a6d1d570576523f2ced2ab25 100644
--- a/servers/slapd/delete.c
+++ b/servers/slapd/delete.c
@@ -45,13 +45,6 @@ do_delete(
     SlapReply	*rs )
 {
 	struct berval dn = BER_BVNULL;
-	struct berval pdn = BER_BVNULL;
-	struct berval org_req_dn = BER_BVNULL;
-	struct berval org_req_ndn = BER_BVNULL;
-	struct berval org_dn = BER_BVNULL;
-	struct berval org_ndn = BER_BVNULL;
-	int	org_managedsait;
-	int manageDSAit;
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, 
@@ -115,7 +108,7 @@ do_delete(
 			"cannot delete the root DSE" );
 		goto cleanup;
 
-	} else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) {
+	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, INFO, "do_delete: conn %d: "
 			"Attempt to delete subschema subentry.\n", op->o_connid, 0, 0 );
@@ -131,6 +124,23 @@ do_delete(
 	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu DEL dn=\"%s\"\n",
 		op->o_connid, op->o_opid, op->o_req_dn.bv_val, 0, 0 );
 
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_delete( op, rs );
+
+cleanup:;
+	slap_graduate_commit_csn( op );
+
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+	return rs->sr_err;
+}
+
+int
+fe_op_delete( Operation *op, SlapReply *rs )
+{
+	struct berval	pdn = BER_BVNULL;
+	int		manageDSAit;
+	
 	manageDSAit = get_manageDSAit( op );
 
 	/*
@@ -172,7 +182,7 @@ do_delete(
 #define pb op->o_pb
 	if ( pb ) {
 		slapi_int_pblock_set_operation( pb, op );
-		slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)dn.bv_val );
+		slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)op->o_req_dn.bv_val );
 		slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
 
 		rs->sr_err = slapi_int_call_plugins( op->o_bd,
@@ -213,7 +223,12 @@ do_delete(
 		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
 #endif
 		{
-			slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
+			struct berval	org_req_dn = BER_BVNULL;
+			struct berval	org_req_ndn = BER_BVNULL;
+			struct berval	org_dn = BER_BVNULL;
+			struct berval	org_ndn = BER_BVNULL;
+			int		org_managedsait;
+			slap_callback 	cb = { NULL, slap_replog_cb, NULL, NULL };
 
 			if ( !repl_user ) {
 				struct berval csn = { 0 , NULL };
@@ -307,10 +322,6 @@ do_delete(
 	}
 #endif /* defined( LDAP_SLAPI ) */
 
-cleanup:
-	slap_graduate_commit_csn( op );
-
-	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
-	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+cleanup:;
 	return rs->sr_err;
 }
diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c
index 27a06ad87cc291727a2db341035266fb877be51f..731f9553229413adb15558dd0050f38451dec9f1 100644
--- a/servers/slapd/extended.c
+++ b/servers/slapd/extended.c
@@ -138,14 +138,6 @@ do_extended(
 	struct berval reqdata = {0, NULL};
 	ber_tag_t tag;
 	ber_len_t len;
-	struct extop_list *ext = NULL;
-
-#if defined(LDAP_SLAPI) 
- 	Slapi_PBlock    *pb = op->o_pb;
- 	SLAPI_FUNC      funcAddr = NULL;
- 	int             extop_rc;
- 	int             msg_sent = FALSE;
-#endif /* defined(LDAP_SLAPI) */
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, "do_extended: conn %d\n", op->o_connid, 0, 0 );
@@ -179,26 +171,6 @@ do_extended(
 		goto done;
 	}
 
-#ifdef LDAP_SLAPI
-	slapi_int_get_extop_plugin( &op->ore_reqoid, &funcAddr ); /* NS-SLAPI extended operation */
-	if( !funcAddr && !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
-#else
-	if( !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
-#endif
-	{
-#ifdef NEW_LOGGING
-		LDAP_LOG( OPERATION, ERR, 
-			"do_extended: conn %d  unsupported operation \"%s\"\n",
-			op->o_connid, op->ore_reqoid.bv_val, 0 );
-#else
-		Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
-			op->ore_reqoid.bv_val, 0 ,0 );
-#endif
-		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
-			"unsupported extended operation" );
-		goto done;
-	}
-
 	tag = ber_peek_tag( op->o_ber, &len );
 	
 	if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
@@ -234,6 +206,54 @@ do_extended(
 		goto done;
 	}
 
+	/* FIXME: temporary? */
+	if ( reqdata.bv_val ) {
+		op->ore_reqdata = &reqdata;
+	}
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_extended( op, rs );
+done:
+	return rs->sr_err;
+}
+
+int
+fe_extended( Operation *op, SlapReply *rs )
+{
+	struct extop_list	*ext = NULL;
+	struct berval		reqdata = BER_BVNULL;
+
+#if defined(LDAP_SLAPI) 
+ 	Slapi_PBlock    	*pb = op->o_pb;
+ 	SLAPI_FUNC      	funcAddr = NULL;
+ 	int             	extop_rc;
+ 	int             	msg_sent = FALSE;
+#endif /* defined(LDAP_SLAPI) */
+
+	if (op->ore_reqdata) {
+		reqdata = *op->ore_reqdata;
+	}
+
+#ifdef LDAP_SLAPI
+	slapi_int_get_extop_plugin( &op->ore_reqoid, &funcAddr ); /* NS-SLAPI extended operation */
+	if( !funcAddr && !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
+#else
+	if( !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
+#endif
+	{
+#ifdef NEW_LOGGING
+		LDAP_LOG( OPERATION, ERR, 
+			"do_extended: conn %d  unsupported operation \"%s\"\n",
+			op->o_connid, op->ore_reqoid.bv_val, 0 );
+#else
+		Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
+			op->ore_reqoid.bv_val, 0 ,0 );
+#endif
+		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
+			"unsupported extended operation" );
+		goto done;
+	}
+
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, DETAIL1, 
 		"do_extended: conn %d  oid=%s\n.", op->o_connid, op->ore_reqoid.bv_val, 0 );
@@ -303,7 +323,6 @@ done2:;
 		}
 	} else { /* start of OpenLDAP extended operation */
 #endif /* defined( LDAP_SLAPI ) */
-		if (reqdata.bv_val) op->ore_reqdata = &reqdata;
 		rs->sr_err = (ext->ext_main)( op, rs );
 
 		if( rs->sr_err != SLAPD_ABANDON ) {
@@ -336,7 +355,7 @@ done2:;
 	} /* end of OpenLDAP extended operation */
 #endif /* LDAP_SLAPI */
 
-done:
+done:;
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/frontend.c b/servers/slapd/frontend.c
new file mode 100644
index 0000000000000000000000000000000000000000..0aedfc0e849eb4348977e879b56e17054ebb58e8
--- /dev/null
+++ b/servers/slapd/frontend.c
@@ -0,0 +1,97 @@
+/* frontend.c - routines for dealing with frontend */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2004 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* Portions Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+#include <sys/stat.h>
+
+#include "slap.h"
+#include "lutil.h"
+#include "lber_pvt.h"
+
+#include "ldap_rq.h"
+
+#ifdef LDAP_SLAPI
+#include "slapi/slapi.h"
+#endif
+
+BackendInfo	slap_frontendInfo;
+BackendDB	slap_frontendDB;
+BackendDB	*frontendDB;
+
+int
+frontend_init( void )
+{
+	/* data */
+	frontendDB = &slap_frontendDB;
+
+	/* ACLs */
+	frontendDB->be_dfltaccess = ACL_READ;
+
+	/* limits */
+	frontendDB->be_def_limit.lms_t_soft = SLAPD_DEFAULT_TIMELIMIT;	/* backward compatible limits */
+	frontendDB->be_def_limit.lms_t_hard = 0;
+	frontendDB->be_def_limit.lms_s_soft = SLAPD_DEFAULT_SIZELIMIT;	/* backward compatible limits */
+	frontendDB->be_def_limit.lms_s_hard = 0;
+	frontendDB->be_def_limit.lms_s_unchecked = -1;			/* no limit on unchecked size */
+	frontendDB->be_def_limit.lms_s_pr = 0;				/* page limit */
+	frontendDB->be_def_limit.lms_s_pr_hide = 0;			/* don't hide number of entries left */
+	frontendDB->be_def_limit.lms_s_pr_total = 0;			/* number of total entries returned by pagedResults equal to hard limit */
+
+	/* suffix */
+	frontendDB->be_suffix = ch_calloc( 2, sizeof( struct berval ) );
+	ber_str2bv( "", 0, 1, &frontendDB->be_suffix[0] );
+	BER_BVZERO( &frontendDB->be_suffix[1] );
+	frontendDB->be_nsuffix = ch_calloc( 2, sizeof( struct berval ) );
+	ber_str2bv( "", 0, 1, &frontendDB->be_nsuffix[0] );
+	BER_BVZERO( &frontendDB->be_nsuffix[1] );
+
+	/* info */
+	frontendDB->bd_info = &slap_frontendInfo;
+
+	/* name */
+	frontendDB->bd_info->bi_type = "frontend";
+
+	/* known controls */
+	frontendDB->bd_info->bi_controls = slap_known_controls;
+
+	/* calls */
+	frontendDB->bd_info->bi_op_add = fe_op_add;
+	frontendDB->bd_info->bi_op_bind = fe_op_bind;
+	frontendDB->bd_info->bi_op_compare = fe_op_compare;
+	frontendDB->bd_info->bi_op_delete = fe_op_delete;
+	frontendDB->bd_info->bi_op_modify = fe_op_modify;
+	frontendDB->bd_info->bi_op_modrdn = fe_op_modrdn;
+	frontendDB->bd_info->bi_op_search = fe_op_search;
+	frontendDB->bd_info->bi_extended = fe_extended;
+
+	return 0;
+}
+
diff --git a/servers/slapd/main.c b/servers/slapd/main.c
index 66e47e63a2e72779ee79804574dedf8eca666a88..47012f76692ae368a3d8d259c8692089d052c4f5 100644
--- a/servers/slapd/main.c
+++ b/servers/slapd/main.c
@@ -656,6 +656,10 @@ unhandled_option:;
 	}
 #endif /* LDAP_SLAPI */
 
+	if ( frontend_init() ) {
+		goto destroy;
+	}
+
 	if ( overlay_init() ) {
 		goto destroy;
 	}
diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c
index 133e216535da27e0a2c039e9cdcd2a3556a9e1df..083ba72120cae96b117b176b09d2ae890f28bc32 100644
--- a/servers/slapd/modify.c
+++ b/servers/slapd/modify.c
@@ -50,14 +50,7 @@ do_modify(
 	ber_len_t	len;
 	Modifications	*modlist = NULL;
 	Modifications	**modtail = &modlist;
-#ifdef LDAP_DEBUG
-	Modifications *tmp;
-#endif
-#ifdef LDAP_SLAPI
-	LDAPMod		**modv = NULL;
-#endif
-	int manageDSAit;
-	int increment = 0;
+	int		increment = 0;
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, "do_modify: enter\n", 0, 0, 0 );
@@ -237,6 +230,37 @@ do_modify(
 		goto cleanup;
 	}
 
+	/* FIXME: temporary */
+	op->orm_modlist = modlist;
+	op->orm_increment = increment;
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_modify( op, rs );
+
+cleanup:
+	slap_graduate_commit_csn( op );
+
+	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 ( modlist != NULL ) slap_mods_free( modlist );
+
+	return rs->sr_err;
+}
+
+int
+fe_op_modify( Operation *op, SlapReply *rs )
+{
+#ifdef LDAP_DEBUG
+	Modifications	*tmp;
+#endif
+	int		manageDSAit;
+	Modifications	*modlist = op->orm_modlist;
+	Modifications	**modtail = &modlist;
+#ifdef LDAP_SLAPI
+	LDAPMod		**modv = NULL;
+#endif
+	int		increment = op->orm_increment;
+	
 	if( op->o_req_ndn.bv_len == 0 ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, ERR, 
@@ -249,7 +273,7 @@ do_modify(
 			"modify upon the root DSE not supported" );
 		goto cleanup;
 
-	} else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) {
+	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
 #ifdef NEW_LOGGING
 		LDAP_LOG( OPERATION, ERR,
 			"do_modify: attempt to modify subschema subentry.\n" , 0, 0, 0  );
@@ -315,7 +339,7 @@ do_modify(
 		int len = 0;
 
 		Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
-			op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
+			op->o_connid, op->o_opid, op->o_req_dn.bv_val, 0, 0 );
 
 		for ( tmp = modlist; tmp != NULL; tmp = tmp->sml_next ) {
 			if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
@@ -391,7 +415,7 @@ do_modify(
 #define pb	op->o_pb
 	if ( pb ) {
 		slapi_int_pblock_set_operation( pb, op );
-		slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val );
+		slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)op->o_req_dn.bv_val );
 		slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
 		modv = slapi_int_modifications2ldapmods( &modlist );
 		slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv );
@@ -550,15 +574,11 @@ do_modify(
 	}
 #endif /* defined( LDAP_SLAPI ) */
 
-cleanup:
-	slap_graduate_commit_csn( op );
-
-	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 ( modlist != NULL ) slap_mods_free( modlist );
+cleanup:;
 #if defined( LDAP_SLAPI )
 	if ( modv != NULL ) slapi_int_free_ldapmods( modv );
 #endif
+
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c
index 84f08f464af43ff48c55013c42faae311fc0d2af..1d567a4c0c1919cc849e17ae15fd94e244125978 100644
--- a/servers/slapd/modrdn.c
+++ b/servers/slapd/modrdn.c
@@ -50,25 +50,16 @@ do_modrdn(
     SlapReply	*rs
 )
 {
-	struct berval dn = BER_BVNULL;
-	struct berval newrdn = BER_BVNULL;
-	struct berval newSuperior = BER_BVNULL;
+	struct berval	dn = BER_BVNULL;
+	struct berval	newrdn = BER_BVNULL;
+	struct berval	newSuperior = BER_BVNULL;
 	ber_int_t	deloldrdn;
 
 	struct berval pnewSuperior = BER_BVNULL;
 
 	struct berval nnewSuperior = BER_BVNULL;
 
-	Backend	*newSuperior_be = NULL;
 	ber_len_t	length;
-	int manageDSAit;
-
-	struct berval pdn = BER_BVNULL;
-	struct berval org_req_dn = BER_BVNULL;
-	struct berval org_req_ndn = BER_BVNULL;
-	struct berval org_dn = BER_BVNULL;
-	struct berval org_ndn = BER_BVNULL;
-	int	org_managedsait;
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 );
@@ -193,33 +184,6 @@ do_modrdn(
 		goto cleanup;
 	}
 
-	if( op->o_req_ndn.bv_len == 0 ) {
-#ifdef NEW_LOGGING
-		LDAP_LOG( OPERATION, ERR,
-			"do_modrdn:  attempt to modify root DSE.\n", 0, 0, 0 );
-#else
-		Debug( LDAP_DEBUG_ANY, "do_modrdn: root dse!\n", 0, 0, 0 );
-#endif
-
-		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
-			"cannot rename the root DSE" );
-		goto cleanup;
-
-	} else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) {
-#ifdef NEW_LOGGING
-		LDAP_LOG( OPERATION, ERR,
-			"do_modrdn: attempt to modify subschema subentry: %s (%ld)\n",
-			global_schemandn.bv_val, (long) global_schemandn.bv_len, 0 );
-#else
-		Debug( LDAP_DEBUG_ANY, "do_modrdn: subschema subentry: %s (%ld)\n",
-			global_schemandn.bv_val, (long) global_schemandn.bv_len, 0 );
-#endif
-
-		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
-			"cannot rename subschema subentry" );
-		goto cleanup;
-	}
-
 	/* FIXME: should have/use rdnPretty / rdnNormalize routines */
 
 	rs->sr_err = dnPrettyNormal( NULL, &newrdn, &op->orr_newrdn, &op->orr_nnewrdn, op->o_tmpmemctx );
@@ -267,6 +231,62 @@ do_modrdn(
 		}
 	}
 
+	/* FIXME: temporary? */
+	op->orr_deleteoldrdn = deloldrdn;
+
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_modrdn( op, rs );
+
+cleanup:
+
+	slap_graduate_commit_csn( op );
+
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+
+	op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );	
+	op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );	
+
+	if ( pnewSuperior.bv_val ) op->o_tmpfree( pnewSuperior.bv_val, op->o_tmpmemctx );
+	if ( nnewSuperior.bv_val ) op->o_tmpfree( nnewSuperior.bv_val, op->o_tmpmemctx );
+
+	return rs->sr_err;
+}
+
+int
+fe_op_modrdn( Operation *op, SlapReply *rs )
+{
+	Backend		*newSuperior_be = NULL;
+	int		manageDSAit;
+	struct berval	pdn = BER_BVNULL;
+	
+	if( op->o_req_ndn.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+		LDAP_LOG( OPERATION, ERR,
+			"do_modrdn:  attempt to modify root DSE.\n", 0, 0, 0 );
+#else
+		Debug( LDAP_DEBUG_ANY, "do_modrdn: root dse!\n", 0, 0, 0 );
+#endif
+
+		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+			"cannot rename the root DSE" );
+		goto cleanup;
+
+	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
+#ifdef NEW_LOGGING
+		LDAP_LOG( OPERATION, ERR,
+			"do_modrdn: attempt to modify subschema subentry: %s (%ld)\n",
+			frontendDB->be_schemandn.bv_val, (long)frontendDB->be_schemandn.bv_len, 0 );
+#else
+		Debug( LDAP_DEBUG_ANY, "do_modrdn: subschema subentry: %s (%ld)\n",
+			frontendDB->be_schemandn.bv_val, (long)frontendDB->be_schemandn.bv_len, 0 );
+#endif
+
+		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+			"cannot rename subschema subentry" );
+		goto cleanup;
+	}
+
 	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MODRDN dn=\"%s\"\n",
 	    op->o_connid, op->o_opid, op->o_req_dn.bv_val, 0, 0 );
 
@@ -310,7 +330,7 @@ do_modrdn(
 	 * the same backend, otherwise we return an error.
 	 */
 	if( op->orr_newSup ) {
-		newSuperior_be = select_backend( &nnewSuperior, 0, 0 );
+		newSuperior_be = select_backend( op->orr_nnewSup, 0, 0 );
 
 		if ( newSuperior_be != op->o_bd ) {
 			/* newSuperior is in different backend */
@@ -325,11 +345,11 @@ do_modrdn(
 #define	pb	op->o_pb
 	if ( pb ) {
 		slapi_int_pblock_set_operation( pb, op );
-		slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val );
-		slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val );
+		slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)op->o_req_dn.bv_val );
+		slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)op->orr_newrdn.bv_val );
 		slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR,
-				(void *)newSuperior.bv_val );
-		slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn );
+				(void *)op->orr_newSup->bv_val );
+		slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)op->orr_deleteoldrdn);
 		slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
 
 		rs->sr_err = slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_PRE_MODRDN_FN, pb );
@@ -368,7 +388,6 @@ do_modrdn(
 #endif
 		{
 			slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
-			op->orr_deleteoldrdn = deloldrdn;
 #ifdef SLAPD_MULTIMASTER
 			if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
 #endif
@@ -379,6 +398,12 @@ do_modrdn(
 			op->o_bd->be_modrdn( op, rs );
 
 			if ( op->o_bd->be_delete ) {
+				struct berval	org_req_dn = BER_BVNULL;
+				struct berval	org_req_ndn = BER_BVNULL;
+				struct berval	org_dn = BER_BVNULL;
+				struct berval	org_ndn = BER_BVNULL;
+				int		org_managedsait;
+
 				org_req_dn = op->o_req_dn;
 				org_req_ndn = op->o_req_ndn;
 				org_dn = op->o_dn;
@@ -390,7 +415,7 @@ do_modrdn(
 
 				while ( rs->sr_err == LDAP_SUCCESS &&
 						op->o_delete_glue_parent ) {
-	                op->o_delete_glue_parent = 0;
+					op->o_delete_glue_parent = 0;
 					if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
 						slap_callback cb = { NULL };
 						cb.sc_response = slap_null_cb;
@@ -404,7 +429,7 @@ do_modrdn(
 					}
 				}
 				op->o_managedsait = org_managedsait;
-	            op->o_dn = org_dn;
+	            		op->o_dn = org_dn;
 				op->o_ndn = org_ndn;
 				op->o_req_dn = org_req_dn;
 				op->o_req_ndn = org_req_ndn;
@@ -448,19 +473,7 @@ do_modrdn(
 	}
 #endif /* defined( LDAP_SLAPI ) */
 
-cleanup:
-
-	slap_graduate_commit_csn( op );
-
-	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
-	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-
-	op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );	
-	op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );	
-
-	if ( pnewSuperior.bv_val ) op->o_tmpfree( pnewSuperior.bv_val, op->o_tmpmemctx );
-	if ( nnewSuperior.bv_val ) op->o_tmpfree( nnewSuperior.bv_val, op->o_tmpmemctx );
-
+cleanup:;
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/operational.c b/servers/slapd/operational.c
index 8e19cc9860dd0feb37d2b0cf815a718a2b2b1ad9..d66d54b0937592dfd761bacad698d456b6ee6a0e 100644
--- a/servers/slapd/operational.c
+++ b/servers/slapd/operational.c
@@ -33,12 +33,12 @@ slap_operational_subschemaSubentry( Backend *be )
 	a->a_desc = slap_schema.si_ad_subschemaSubentry;
 
 	a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
-	ber_dupbv( a->a_vals, &global_schemadn );
+	ber_dupbv( a->a_vals, &frontendDB->be_schemadn );
 	a->a_vals[1].bv_len = 0;
 	a->a_vals[1].bv_val = NULL;
 
 	a->a_nvals = ch_malloc( 2 * sizeof( struct berval ) );
-	ber_dupbv( a->a_nvals, &global_schemandn );
+	ber_dupbv( a->a_nvals, &frontendDB->be_schemandn );
 	a->a_nvals[1].bv_len = 0;
 	a->a_nvals[1].bv_val = NULL;
 
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index eee6982e237043b9d3f5ce965980a0b165efa944..b0343fa8f5011475a4f2ccc92830f429ee875194 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -1251,18 +1251,13 @@ LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_auth;
 LDAP_SLAPD_V (int)		slap_conn_max_pending;
 LDAP_SLAPD_V (int)		slap_conn_max_pending_auth;
 
-LDAP_SLAPD_V (slap_mask_t)	global_restrictops;
 LDAP_SLAPD_V (slap_mask_t)	global_allows;
 LDAP_SLAPD_V (slap_mask_t)	global_disallows;
-LDAP_SLAPD_V (slap_mask_t)	global_requires;
-LDAP_SLAPD_V (slap_ssf_set_t)	global_ssf_set;
 
-LDAP_SLAPD_V (BerVarray)		default_referral;
+LDAP_SLAPD_V (BerVarray)	default_referral;
 LDAP_SLAPD_V (char *)		replogfile;
 LDAP_SLAPD_V (const char) 	Versionstr[];
-LDAP_SLAPD_V (struct slap_limits_set)		deflimit;
 
-LDAP_SLAPD_V (slap_access_t)	global_default_access;
 LDAP_SLAPD_V (int)		global_gentlehup;
 LDAP_SLAPD_V (int)		global_idletimeout;
 LDAP_SLAPD_V (int)		global_schemacheck;
@@ -1274,9 +1269,6 @@ LDAP_SLAPD_V (int)		ldap_syslog;
 LDAP_SLAPD_V (struct berval)	default_search_base;
 LDAP_SLAPD_V (struct berval)	default_search_nbase;
 
-LDAP_SLAPD_V (struct berval)	global_schemadn;
-LDAP_SLAPD_V (struct berval)	global_schemandn;
-
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t)	num_sent_mutex;
 LDAP_SLAPD_V (unsigned long)		num_bytes_sent;
 LDAP_SLAPD_V (unsigned long)		num_pdu_sent;
@@ -1311,8 +1303,6 @@ LDAP_SLAPD_V (ldap_pvt_thread_mutex_t)	passwd_mutex;
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t)	gmtime_mutex;
 #endif
 
-LDAP_SLAPD_V (AccessControl *) global_acl;
-
 LDAP_SLAPD_V (ber_socket_t)	dtblsize;
 
 LDAP_SLAPD_V (int)		use_reverse_lookup;
@@ -1335,6 +1325,24 @@ LDAP_SLAPD_F (int) do_search LDAP_P((Operation *op, SlapReply *rs));
 LDAP_SLAPD_F (int) do_unbind LDAP_P((Operation *op, SlapReply *rs));
 LDAP_SLAPD_F (int) do_extended LDAP_P((Operation *op, SlapReply *rs));
 
+/*
+ * frontend operations
+ */
+#if 0
+LDAP_SLAPD_F (int) fe_op_abandon LDAP_P((Operation *op, SlapReply *rs));
+#endif
+LDAP_SLAPD_F (int) fe_op_add LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_bind LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_compare LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_delete LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_modify LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_modrdn LDAP_P((Operation *op, SlapReply *rs));
+LDAP_SLAPD_F (int) fe_op_search LDAP_P((Operation *op, SlapReply *rs));
+#if 0
+LDAP_SLAPD_F (int) fe_op_unbind LDAP_P((Operation *op, SlapReply *rs));
+#endif
+LDAP_SLAPD_F (int) fe_extended LDAP_P((Operation *op, SlapReply *rs));
+
 LDAP_END_DECL
 
 #endif /* PROTO_SLAP_H */
diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c
index 8b006652f3e4217a17dc88e184ba48b684ce4d67..ef142d08117094b0b89054cd23a4da4786ff83bb 100644
--- a/servers/slapd/schema.c
+++ b/servers/slapd/schema.c
@@ -61,8 +61,8 @@ schema_info( Entry **entry, const char **text )
 	/* backend-specific schema info should be created by the
 	 * backend itself
 	 */
-	ber_dupbv( &e->e_name, &global_schemadn );
-	ber_dupbv( &e->e_nname, &global_schemandn );
+	ber_dupbv( &e->e_name, &frontendDB->be_schemadn );
+	ber_dupbv( &e->e_nname, &frontendDB->be_schemandn );
 	e->e_private = NULL;
 
 	vals[0].bv_val = "subentry";
@@ -93,7 +93,7 @@ schema_info( Entry **entry, const char **text )
 	{
 		int rc;
 		AttributeDescription *desc = NULL;
-		struct berval rdn = global_schemadn;
+		struct berval rdn = frontendDB->be_schemadn;
 		vals[0].bv_val = strchr( rdn.bv_val, '=' );
 
 		if( vals[0].bv_val == NULL ) {
@@ -113,11 +113,11 @@ schema_info( Entry **entry, const char **text )
 			return LDAP_OTHER;
 		}
 
-		nvals[0].bv_val = strchr( global_schemandn.bv_val, '=' );
+		nvals[0].bv_val = strchr( frontendDB->be_schemandn.bv_val, '=' );
 		assert( nvals[0].bv_val );
 		nvals[0].bv_val++;
-		nvals[0].bv_len = global_schemandn.bv_len -
-			(nvals[0].bv_val - global_schemandn.bv_val);
+		nvals[0].bv_len = frontendDB->be_schemandn.bv_len -
+			(nvals[0].bv_val - frontendDB->be_schemandn.bv_val);
 
 		if( attr_merge_one( e, desc, vals, nvals ) ) {
 			/* Out of memory, do something about it */
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index 6f0d30e18e8501bab69292177b22f7cd2684b8c9..9df49bf0cbb975f06b34e0d935effa49fd470d71 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -51,11 +51,6 @@ do_search(
 {
 	struct berval base = BER_BVNULL;
 	ber_len_t	siz, off, i;
-	int			manageDSAit;
-	int			be_manageDSAit;
-#ifdef LDAP_SLAPI
-	char		**attrs = NULL;
-#endif
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, "do_search: conn %d\n", op->o_connid, 0, 0 );
@@ -269,6 +264,44 @@ do_search(
 		}
 	}
 
+	op->o_bd = frontendDB;
+	rs->sr_err = frontendDB->be_search( op, rs );
+
+return_results:;
+	if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) {
+		return rs->sr_err;
+	}
+	if ( ( op->o_sync_slog_size != -1 ) ) {
+		return rs->sr_err;
+	}
+	if ( !BER_BVISNULL( &op->o_req_dn ) ) {
+		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	}
+	if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
+		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+	}
+	if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
+		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+	}
+	if ( op->ors_filter != NULL) {
+		filter_free_x( op, op->ors_filter );
+	}
+	if ( op->ors_attrs != NULL ) {
+		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
+	}
+
+	return rs->sr_err;
+}
+
+int
+fe_op_search( Operation *op, SlapReply *rs )
+{
+	int			manageDSAit;
+	int			be_manageDSAit;
+#ifdef LDAP_SLAPI
+	char			**attrs = NULL;
+#endif
+
 	manageDSAit = get_manageDSAit( op );
 
 	/* fake while loop to allow breaking out */
@@ -299,7 +332,7 @@ do_search(
 #endif /* LDAP_SLAPI */
 			rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text );
 
-		} else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) {
+		} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
 			/* check restrictions */
 			if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
 				send_ldap_result( op, rs );
@@ -429,29 +462,11 @@ do_search(
 	if ( op->o_pb ) call_search_postop_plugins( op );
 #endif /* LDAP_SLAPI */
 
-return_results:;
-	if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) return rs->sr_err;
-	if ( ( op->o_sync_slog_size != -1 ) ) return rs->sr_err;
-
-	if( !BER_BVISNULL( &op->o_req_dn ) ) {
-		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
-	}
-	if( !BER_BVISNULL( &op->o_req_ndn ) ) {
-		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
-	}
-
-	if( !BER_BVISNULL( &op->ors_filterstr ) ) {
-		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-	}
-	if( op->ors_filter != NULL) filter_free_x( op, op->ors_filter );
-	if( op->ors_attrs != NULL ) {
-		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
-	}
-
 #ifdef LDAP_SLAPI
 	if( attrs != NULL) op->o_tmpfree( attrs, op->o_tmpmemctx );
 #endif /* LDAP_SLAPI */
 
+return_results:;
 	return rs->sr_err;
 }
 
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index d78df940a00e83339bcbba7846cbbd5c266fefd9..0cedcf8fcc7acd646c3a504035b6e7342e99e1a6 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1280,6 +1280,7 @@ LDAP_SLAPD_V (int) nBackendInfo;
 LDAP_SLAPD_V (int) nBackendDB;
 LDAP_SLAPD_V (BackendInfo *) backendInfo;
 LDAP_SLAPD_V (BackendDB *) backendDB;
+LDAP_SLAPD_V (BackendDB *) frontendDB;
 
 LDAP_SLAPD_V (int) slapMode;	
 #define SLAP_UNDEFINED_MODE	0x0000
@@ -1615,6 +1616,7 @@ typedef struct req_bind_s {
 	struct berval rb_cred;
 	struct berval rb_edn;
 	slap_ssf_t rb_ssf;
+	struct berval rb_tmp_mech;	/* FIXME: temporary */
 } req_bind_s;
 
 typedef struct req_search_s {
@@ -1636,6 +1638,7 @@ typedef struct req_compare_s {
 
 typedef struct req_modify_s {
 	Modifications *rs_modlist;
+	int rs_increment;		/* FIXME: temporary */
 } req_modify_s;
 
 typedef struct req_modrdn_s {
@@ -1648,6 +1651,7 @@ typedef struct req_modrdn_s {
 
 typedef struct req_add_s {
 	Entry *rs_e;
+	Modifications *rs_modlist;	/* FIXME: temporary */
 } req_add_s;
 
 typedef struct req_abandon_s {
@@ -2051,6 +2055,7 @@ typedef struct slap_op {
 #define orb_cred oq_bind.rb_cred
 #define orb_edn oq_bind.rb_edn
 #define orb_ssf oq_bind.rb_ssf
+#define orb_tmp_mech oq_bind.rb_tmp_mech
 
 #define ors_scope oq_search.rs_scope
 #define ors_deref oq_search.rs_deref
@@ -2070,8 +2075,10 @@ typedef struct slap_op {
 
 #define orc_ava oq_compare.rs_ava
 #define ora_e oq_add.rs_e
+#define ora_modlist oq_add.rs_modlist
 #define orn_msgid oq_abandon.rs_msgid
 #define orm_modlist oq_modify.rs_modlist
+#define orm_increment oq_modify.rs_increment
 
 #define ore_reqoid oq_extended.rs_reqoid
 #define ore_reqdata oq_extended.rs_reqdata
diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c
index 637dfe0d90715b50057ff508909ff591a5915df4..73e52e4601bfab8a605ea63cfd28a4731bc764c6 100644
--- a/servers/slapd/slapcommon.c
+++ b/servers/slapd/slapcommon.c
@@ -351,6 +351,11 @@ slap_tool_init(
 		exit( EXIT_FAILURE );
 	}
 
+	if ( frontend_init() ) {
+		fprintf( stderr, "%s: frontend_init failed!\n", progname );
+		exit( EXIT_FAILURE );
+	}
+
 	if ( overlay_init() ) {
 		fprintf( stderr, "%s: overlay_init failed!\n", progname );
 		exit( EXIT_FAILURE );