diff --git a/CHANGES b/CHANGES
index 90bd8c8dcc5d597183d1b7e30f19ab4e616102a4..2e59820723532f4a1da54a2900328a995cac620c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,7 @@ OpenLDAP 2.4.14 Engineering
 	Fixed slapd connection assert (ITS#5835)
 	Fixed slapd epoll handling (ITS#5886)
 	Fixed slapd frontend/backend options handling (ITS#5857)
+	Fixed slapd manageDSAit with glue entries (ITS#5921)
 	Fixed slapd syncrepl rename handling (ITS#5809)
 	Fixed slapd syncrepl MMR when adding new server (ITS#5850)
 	Fixed slapd syncrepl MMR with deleted entries (ITS#5843)
diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c
index 30074f93f36a8422827116d8f8122d16201fe062..921c41d573f8fd5408811a25ec24d02da19b4a7e 100644
--- a/servers/slapd/back-bdb/add.c
+++ b/servers/slapd/back-bdb/add.c
@@ -94,7 +94,7 @@ txnReturn:
 
 	/* check entry's schema */
 	rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
-		get_relax(op), 1, &rs->sr_text, textbuf, textlen );
+		get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			LDAP_XSTRING(bdb_add) ": entry failed schema check: "
diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c
index 088accdccad910e219285917a5748d02d6800e54..c6e3cd03f6d0494a12cd5a48df3d41b96586fcc9 100644
--- a/servers/slapd/back-bdb/modify.c
+++ b/servers/slapd/back-bdb/modify.c
@@ -27,6 +27,44 @@ static struct berval scbva[] = {
 	BER_BVNULL
 };
 
+static void
+bdb_modify_idxflags(
+	Operation *op,
+	AttributeDescription *desc,
+	int got_delete,
+	Attribute *newattrs,
+	Attribute *oldattrs )
+{
+	struct berval	ix_at;
+	AttrInfo	*ai;
+
+	/* check if modified attribute was indexed
+	 * but not in case of NOOP... */
+	ai = bdb_index_mask( op->o_bd, desc, &ix_at );
+	if ( ai ) {
+		if ( got_delete ) {
+			Attribute 	*ap;
+			struct berval	ix2;
+
+			ap = attr_find( oldattrs, desc );
+			if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL;
+
+			/* Find all other attrs that index to same slot */
+			for ( ap = newattrs; ap; ap = ap->a_next ) {
+				ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 );
+				if ( ai && ix2.bv_val == ix_at.bv_val )
+					ap->a_flags |= SLAP_ATTR_IXADD;
+			}
+
+		} else {
+			Attribute 	*ap;
+
+			ap = attr_find( newattrs, desc );
+			if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD;
+		}
+	}
+}
+
 int bdb_modify_internal(
 	Operation *op,
 	DB_TXN *tid,
@@ -43,7 +81,6 @@ int bdb_modify_internal(
 	Attribute 	*ap;
 	int			glue_attr_delete = 0;
 	int			got_delete;
-	AttrInfo *ai;
 
 	Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n",
 		e->e_id, e->e_dn, 0);
@@ -89,7 +126,6 @@ int bdb_modify_internal(
 	}
 
 	for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
-		struct berval ix_at;
 		mod = &ml->sml_mod;
 		got_delete = 0;
 
@@ -202,31 +238,17 @@ int bdb_modify_internal(
 
 		if ( glue_attr_delete ) e->e_ocflags = 0;
 
+
 		/* check if modified attribute was indexed
 		 * but not in case of NOOP... */
-		ai = bdb_index_mask( op->o_bd, mod->sm_desc, &ix_at );
-		if ( ai && !op->o_noop ) {
-			if ( got_delete ) {
-				struct berval ix2;
-
-				ap = attr_find( save_attrs, mod->sm_desc );
-				if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL;
-
-				/* Find all other attrs that index to same slot */
-				for ( ap = e->e_attrs; ap; ap=ap->a_next ) {
-					ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 );
-					if ( ai && ix2.bv_val == ix_at.bv_val )
-						ap->a_flags |= SLAP_ATTR_IXADD;
-				}
-			} else {
-				ap = attr_find( e->e_attrs, mod->sm_desc );
-				if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD;
-			}
+		if ( !op->o_noop ) {
+			bdb_modify_idxflags( op, mod->sm_desc, got_delete, e->e_attrs, save_attrs );
 		}
 	}
 
 	/* check that the entry still obeys the schema */
-	rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0,
+	ap = NULL;
+	rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0, &ap,
 		text, textbuf, textlen );
 	if ( rc != LDAP_SUCCESS || op->o_noop ) {
 		attrs_free( e->e_attrs );
@@ -246,6 +268,15 @@ int bdb_modify_internal(
 		return rc;
 	}
 
+	/* structuralObjectClass modified! */
+	if ( ap ) {
+		assert( ap->a_desc == slap_schema.si_ad_structuralObjectClass );
+		if ( !op->o_noop ) {
+			bdb_modify_idxflags( op, slap_schema.si_ad_structuralObjectClass,
+				1, e->e_attrs, save_attrs );
+		}
+	}
+
 	/* update the indices of the modified attributes */
 
 	/* start with deleting the old index entries */
diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c
index 1fb5e526853e0ef33232d11b7feba4c87ea4fc73..4625af8c8d71a0d554076661401e02a3ebe1cbd9 100644
--- a/servers/slapd/back-ldif/ldif.c
+++ b/servers/slapd/back-ldif/ldif.c
@@ -1065,7 +1065,7 @@ apply_modify_to_entry(
 			entry->e_ocflags = 0;
 		}
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check( op, entry, NULL, 0, 0,
+		rc = entry_schema_check( op, entry, NULL, 0, 0, NULL,
 			  &rs->sr_text, textbuf, sizeof( textbuf ) );
 	}
 
@@ -1230,7 +1230,7 @@ ldif_back_add( Operation *op, SlapReply *rs )
 
 	Debug( LDAP_DEBUG_TRACE, "ldif_back_add: \"%s\"\n", e->e_dn, 0, 0 );
 
-	rc = entry_schema_check( op, e, NULL, 0, 1,
+	rc = entry_schema_check( op, e, NULL, 0, 1, NULL,
 		&rs->sr_text, textbuf, sizeof( textbuf ) );
 	if ( rc != LDAP_SUCCESS )
 		goto send_res;
diff --git a/servers/slapd/back-monitor/log.c b/servers/slapd/back-monitor/log.c
index 70c45a2ff10be0e47e5b4c6e48764d647ad6e659..d772fd260f023fdaade5db251db3058a8220f8ea 100644
--- a/servers/slapd/back-monitor/log.c
+++ b/servers/slapd/back-monitor/log.c
@@ -181,7 +181,7 @@ monitor_subsys_log_modify(
 		}
 
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check( op, e, save_attrs, 0, 0,
+		rc = entry_schema_check( op, e, save_attrs, 0, 0, NULL,
 			&text, textbuf, sizeof( textbuf ) );
 		if ( rc != LDAP_SUCCESS ) {
 			rs->sr_err = rc;
diff --git a/servers/slapd/back-ndb/add.cpp b/servers/slapd/back-ndb/add.cpp
index 91e32d9444c4c056f7516eb3cae79d0b9158a460..4efdbcd14f19c96993b059bda794400fc2668d9b 100644
--- a/servers/slapd/back-ndb/add.cpp
+++ b/servers/slapd/back-ndb/add.cpp
@@ -54,7 +54,7 @@ ndb_back_add(Operation *op, SlapReply *rs )
 
 	/* check entry's schema */
 	rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
-		get_relax(op), 1, &rs->sr_text, textbuf, textlen );
+		get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_TRACE,
 			LDAP_XSTRING(ndb_back_add) ": entry failed schema check: "
diff --git a/servers/slapd/back-ndb/modify.cpp b/servers/slapd/back-ndb/modify.cpp
index 275873c362c277f23f26d0f81c4c56d3156952d0..3733069c98ac0cef0f59719e2f550fd6df9ceba7 100644
--- a/servers/slapd/back-ndb/modify.cpp
+++ b/servers/slapd/back-ndb/modify.cpp
@@ -322,7 +322,7 @@ int ndb_modify_internal(
 	}
 
 	/* check that the entry still obeys the schema */
-	rc = entry_schema_check( op, NA->e, NULL, get_relax(op), 0,
+	rc = entry_schema_check( op, NA->e, NULL, get_relax(op), 0, NULL,
 		text, textbuf, textlen );
 	if ( rc != LDAP_SUCCESS || op->o_noop ) {
 		if ( rc != LDAP_SUCCESS ) {
diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c
index 546441e2e9fe2831f829ebf15e72193ad98cbed4..ae88f76e4938b4fc0215c4f5db04a3153ce57439 100644
--- a/servers/slapd/back-sql/add.c
+++ b/servers/slapd/back-sql/add.c
@@ -962,7 +962,7 @@ backsql_add( Operation *op, SlapReply *rs )
 	if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
 		char		textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
 
-		rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0, 1,
+		rs->sr_err = entry_schema_check( op, op->ora_e, NULL, 0, 1, NULL,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE, "   backsql_add(\"%s\"): "
diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c
index f7cfe44f7ab684aa7698db48f2386b29492bc246..941bc3754831ae5e79f04209473fd6e475a4bf3c 100644
--- a/servers/slapd/back-sql/modify.c
+++ b/servers/slapd/back-sql/modify.c
@@ -152,7 +152,7 @@ backsql_modify( Operation *op, SlapReply *rs )
 			goto do_transact;
 		}
 
-		rs->sr_err = entry_schema_check( op, &m, NULL, 0, 0,
+		rs->sr_err = entry_schema_check( op, &m, NULL, 0, 0, NULL,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE, "   backsql_modify(\"%s\"): "
diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c
index 0f273e145a4a968bc5f539ed7ea1e467496b9c91..fafd98ee545029d981ad7737330f340a070d0a8a 100644
--- a/servers/slapd/back-sql/modrdn.c
+++ b/servers/slapd/back-sql/modrdn.c
@@ -455,7 +455,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
 		e_id = bsi.bsi_base_id;
 
-		rs->sr_err = entry_schema_check( op, &r, NULL, 0, 0,
+		rs->sr_err = entry_schema_check( op, &r, NULL, 0, 0, NULL,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
 			Debug( LDAP_DEBUG_TRACE, "   backsql_modrdn(\"%s\"): "
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index 545ce4a3b2c482fecc502fdaa2dc9f43fe3c6772..477e29e2660e71560b7d58f5443ce5da13e83847 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -4695,7 +4695,7 @@ config_back_add( Operation *op, SlapReply *rs )
 	{
 		char textbuf[SLAP_TEXT_BUFLEN];
 		size_t textlen = sizeof textbuf;
-		rs->sr_err = entry_schema_check(op, op->ora_e, NULL, 0, 1,
+		rs->sr_err = entry_schema_check(op, op->ora_e, NULL, 0, 1, NULL,
 			&rs->sr_text, textbuf, sizeof( textbuf ) );
 		if ( rs->sr_err != LDAP_SUCCESS )
 			goto out;
@@ -4941,7 +4941,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
 	
 	if ( rc == LDAP_SUCCESS) {
 		/* check that the entry still obeys the schema */
-		rc = entry_schema_check(op, e, NULL, 0, 0,
+		rc = entry_schema_check(op, e, NULL, 0, 0, NULL,
 			&rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
 	}
 	if ( rc ) goto out_noop;
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 5837bb50f2b35236e5ed15f43a404d2ac4472643..6e8c0fe47c2af8986baf09725a340623539d2c8b 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -1643,6 +1643,7 @@ LDAP_SLAPD_F( int ) entry_schema_check(
 	Attribute *attrs,
 	int manage,
 	int add,
+	Attribute **socp,
 	const char** text,
 	char *textbuf, size_t textlen );
 
diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c
index a49517f7c5986b3f2d5939b079ed34c486d5f8cc..b466613c47d30e9a93e5a5f46c8db210909f458a 100644
--- a/servers/slapd/schema_check.c
+++ b/servers/slapd/schema_check.c
@@ -49,6 +49,7 @@ entry_schema_check(
 	Attribute *oldattrs,
 	int manage,
 	int add,
+	Attribute **socp,
 	const char** text,
 	char *textbuf, size_t textlen )
 {
@@ -212,15 +213,28 @@ got_soc:
 		rc = LDAP_OBJECT_CLASS_VIOLATION;
 		goto done;
 
-	} else if ( sc != slap_schema.si_oc_glue && sc != oc ) {
-		snprintf( textbuf, textlen, 
-			"structural object class modification "
-			"from '%s' to '%s' not allowed",
-			asc->a_vals[0].bv_val, oc->soc_cname.bv_val );
-		rc = LDAP_NO_OBJECT_CLASS_MODS;
-		goto done;
-	} else if ( sc == slap_schema.si_oc_glue ) {
+	} else if ( sc != oc ) {
+		if ( !manage && sc != slap_schema.si_oc_glue ) {
+			snprintf( textbuf, textlen, 
+				"structural object class modification "
+				"from '%s' to '%s' not allowed",
+				asc->a_vals[0].bv_val, oc->soc_cname.bv_val );
+			rc = LDAP_NO_OBJECT_CLASS_MODS;
+			goto done;
+		}
+
+		assert( asc->a_vals != NULL );
+		assert( !BER_BVISNULL( &asc->a_vals[0] ) );
+		assert( BER_BVISNULL( &asc->a_vals[1] ) );
+		assert( asc->a_nvals == asc->a_vals );
+
+		/* draft-zeilenga-ldap-relax: automatically modify
+		 * structuralObjectClass if changed with relax */
 		sc = oc;
+		ber_bvreplace( &asc->a_vals[ 0 ], &sc->soc_cname );
+		if ( socp ) {
+			*socp = asc;
+		}
 	}
 
 	/* naming check */
diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c
index a0bf97e3ee5b09d22e27c25e06ae6092f0d547f5..fd9558e52393517cb46bba88b0d8d66c9b25431c 100644
--- a/servers/slapd/slapadd.c
+++ b/servers/slapd/slapadd.c
@@ -192,7 +192,7 @@ slapadd( int argc, char **argv )
 			op->o_bd = be;
 
 			if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
-				rc = entry_schema_check( op, e, NULL, manage, 1,
+				rc = entry_schema_check( op, e, NULL, manage, 1, NULL,
 					&text, textbuf, textlen );
 
 				if( rc != LDAP_SUCCESS ) {
diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c
index ecf351d90dbe8324b77d831489fd87714123eddd..e6613e4d1259d76f2c51b1f8ee7df560a74dce8d 100644
--- a/servers/slapd/slapi/slapi_utils.c
+++ b/servers/slapd/slapi/slapi_utils.c
@@ -3117,7 +3117,7 @@ int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
 
 	pb->pb_op->o_bd = select_backend( &e->e_nname, 0 );
 	if ( pb->pb_op->o_bd != NULL ) {
-		rc = entry_schema_check( pb->pb_op, e, NULL, 0, 0,
+		rc = entry_schema_check( pb->pb_op, e, NULL, 0, 0, NULL,
 			&text, textbuf, textlen );
 	}
 	pb->pb_op->o_bd = be_orig;