From b0f06da400f349dbfbdb336505d146a70970e706 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Fri, 5 Jan 2007 16:18:42 +0000 Subject: [PATCH] improve disconnect handling --- doc/man/man5/slapo-retcode.5 | 10 +++++---- servers/slapd/overlays/retcode.c | 36 +++++++++++++++++++++++++------- tests/data/slapd-retcode.conf | 5 +++++ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/doc/man/man5/slapo-retcode.5 b/doc/man/man5/slapo-retcode.5 index 81a3faa760..313dd228eb 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 [op=] [text=] .B [ref=] [sleeptime=] [matched=] -.B [unsolicited=[:]] [flags=disconnect[,...]] +.B [unsolicited=[:]] [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 198709febe..4c8af88986 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 1523330024..a9984009ce 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 -- 2.39.5