diff --git a/doc/man/man5/slapo-retcode.5 b/doc/man/man5/slapo-retcode.5
index 81a3faa76065060caae305f8f760c17b2f34cf46..313dd228ebc026ad921fb35eccc2a0650b9a8a40 100644
--- a/doc/man/man5/slapo-retcode.5
+++ b/doc/man/man5/slapo-retcode.5
@@ -58,7 +58,7 @@ If not defined, the suffix of the database is used.
 .hy 0
 .B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>]
 .B [ref=<referral>] [sleeptime=<sec>] [matched=<DN>]
-.B [unsolicited=<OID>[:<data>]] [flags=disconnect[,...]]
+.B [unsolicited=<OID>[:<data>]] [flags=[{pre|post}-]disconnect[,...]]
 .RS
 A dynamically generated entry, located below \fBretcode\-parent\fP.
 The \fBerrCode\fP is the number of the response code;
@@ -79,9 +79,10 @@ The \fBunsolicited\fP field can be used to cause the return
 of an RFC 4511 unsolicited response message; if \fBOID\fP
 is not "0", an extended response is generated, with the optional
 \fBdata\fP appended.
-If \fBflags\fP contains \fBdisconnect\fP, 
+If \fBflags\fP contains \fBdisconnect\fP, or \fBpre-disconnect\fP,
 .BR slapd (8)
-disconnects abruptly, without notice.
+disconnects abruptly, without notice; \fBpost-disconnect\fP
+causes disconnection right after sending response as appropriate.
 .RE
 .TP
 .B retcode\-indir
@@ -186,7 +187,8 @@ in RFC 4511 unsolicited response:
 .LP
 If TRUE,
 .BR slapd (8)
-disconnects abruptly without notice:
+disconnects abruptly without notice; if FALSE, it disconnects
+after sending response as appropriate:
 .RS 4
 ( 1.3.6.1.4.1.4203.666.11.4.1.8
     NAME ( 'errDisconnect' )
diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c
index 198709febe54b1b3311db6e32771e6cc25792b45..4c8af8898695bcc2e7c3cb3509c6e1f9ccb2da3f 100644
--- a/servers/slapd/overlays/retcode.c
+++ b/servers/slapd/overlays/retcode.c
@@ -79,7 +79,8 @@ typedef struct retcode_item_t {
 	struct berval		rdi_unsolicited_data;
 
 	unsigned		rdi_flags;
-#define	RDI_DISCONNECT		(0x1U)
+#define	RDI_PRE_DISCONNECT	(0x1U)
+#define	RDI_POST_DISCONNECT	(0x2U)
 
 	struct retcode_item_t	*rdi_next;
 } retcode_item_t;
@@ -413,7 +414,7 @@ retcode_op_func( Operation *op, SlapReply *rs )
 		rs->sr_text = "retcode not found";
 
 	} else {
-		if ( rdi->rdi_flags & RDI_DISCONNECT ) {
+		if ( rdi->rdi_flags & RDI_PRE_DISCONNECT ) {
 			return rs->sr_err = SLAPD_DISCONNECT;
 		}
 
@@ -492,6 +493,10 @@ retcode_op_func( Operation *op, SlapReply *rs )
 		}
 		rs->sr_matched = NULL;
 		rs->sr_text = NULL;
+
+		if ( rdi && rdi->rdi_flags & RDI_POST_DISCONNECT ) {
+			return rs->sr_err = SLAPD_DISCONNECT;
+		}
 		break;
 	}
 
@@ -536,6 +541,7 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
 	Attribute	*a;
 	int		err;
 	char		*next;
+	int		disconnect = 0;
 
 	if ( get_manageDSAit( op ) ) {
 		return SLAP_CB_CONTINUE;
@@ -572,8 +578,11 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
 
 	/* disconnect */
 	a = attr_find( e->e_attrs, ad_errDisconnect );
-	if ( a != NULL && bvmatch( &a->a_nvals[ 0 ], &slap_true_bv ) ) {
-		return rs->sr_err = SLAPD_DISCONNECT;
+	if ( a != NULL ) {
+		if ( bvmatch( &a->a_nvals[ 0 ], &slap_true_bv ) ) {
+			return rs->sr_err = SLAPD_DISCONNECT;
+		}
+		disconnect = 1;
 	}
 
 	/* error code */
@@ -685,8 +694,12 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
 		op->o_bd = o_bd;
 		op->o_callback = o_callback;
 	}
-	
+
 	if ( rs->sr_err != LDAP_SUCCESS ) {
+		if ( disconnect ) {
+			return rs->sr_err = SLAPD_DISCONNECT;
+		}
+	
 		op->o_abandon = 1;
 		return rs->sr_err;
 	}
@@ -1001,13 +1014,20 @@ retcode_db_config(
 
 				} else if ( strncasecmp( argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 )
 				{
-					if ( strcasecmp( &argv[ i ][ STRLENOF( "flags=" ) ], "disconnect" ) == 0 ) {
-						rdi.rdi_flags |= RDI_DISCONNECT;
+					char *arg = &argv[ i ][ STRLENOF( "flags=" ) ];
+					if ( strcasecmp( arg, "disconnect" ) == 0 ) {
+						rdi.rdi_flags |= RDI_PRE_DISCONNECT;
+
+					} else if ( strcasecmp( arg, "pre-disconnect" ) == 0 ) {
+						rdi.rdi_flags |= RDI_PRE_DISCONNECT;
+
+					} else if ( strcasecmp( arg, "post-disconnect" ) == 0 ) {
+						rdi.rdi_flags |= RDI_POST_DISCONNECT;
 
 					} else {
 						fprintf( stderr, "%s: line %d: retcode: "
 							"unknown flag \"%s\".\n",
-							fname, lineno, &argv[ i ][ STRLENOF( "flags=" ) ] );
+							fname, lineno, arg );
 						return 1;
 					}
 
diff --git a/tests/data/slapd-retcode.conf b/tests/data/slapd-retcode.conf
index 1523330024866dc39f8bef1bb27a5399cdd6853e..a9984009cee57e3454a52b3df214c0065e21bfb1 100644
--- a/tests/data/slapd-retcode.conf
+++ b/tests/data/slapd-retcode.conf
@@ -51,4 +51,9 @@ overlay		retcode
 retcode-parent	"ou=RetCodes,dc=example,dc=com"
 include		@DATADIR@/retcode.conf
 
+retcode-item	"cn=Unsolicited"		0x00 unsolicited="0"
+retcode-item	"cn=Notice of Disconnect"	0x00 unsolicited="1.3.6.1.4.1.1466.20036"
+retcode-item	"cn=Pre-disconnect"		0x34 flags="pre-disconnect"
+retcode-item	"cn=Post-disconnect"		0x34 flags="post-disconnect"
+
 #monitor#database	monitor